/**
  * A method to test the convertDateToOperationIntervalID() method.
  */
 function testConvertDateToOperationIntervalID()
 {
     // 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');
     $result = OX_OperationInterval::convertDateToOperationIntervalID($date, 60);
     $this->assertEqual($result, 0);
     // Test a date in the last operation interval ID in the week before the test was
     // written, using an operation interval of 30 minutes
     $date = new Date('2004-08-14 23:40:00');
     $result = OX_OperationInterval::convertDateToOperationIntervalID($date, 30);
     $this->assertEqual($result, 335);
 }
 /**
  * A private method to calcuate the number of impressions an advertisement needs to deliver
  * in the next operation interval, based on the total number of impressions the ad needs to
  * deliver over the rest of the campaigns, the operaion intervals the ad will be active
  * in, and the average zone pattern of the zones the ad is linked to.
  *
  * @access private
  * @param OA_Maintenance_Priority_Ad $oAd An ad object, representing the advertisement.
  * @param integer $totalRequiredAdImpressions The total number of impressions the advertisement
  *                                            needs to deliver.
  * @param PEAR::Date $oDate A Date object, set in the current operation interval.
  * @param PEAR::Date $oCampaignExpiryDate A Date object representing the end of the advertisement's
  *                                        parent campaign.
  * @param OA_Maintenance_Priority_DeliveryLimitation $oDeliveryLimitation The delivery limitation
  *                                                                        object for the ad.
  * @param array $aAdZones An array of arrays, no particular index in the outer array, in the
  *                        inner arrays, each as an index "zone_id" containing one zone ID that
  *                        the ad is linked to.
  * @return integer The number of impressions the advertisement should deliver in the next
  *                 operation interval.
  */
 function _getAdImpressions($oAd, $totalRequiredAdImpressions, $oDate, $oCampaignExpiryDate, $oDeliveryLimitation, $aAdZones)
 {
     // Check the parameters, and return 0 impressions if not valid
     if (!is_a($oAd, 'OA_Maintenance_Priority_Ad') || !is_numeric($totalRequiredAdImpressions) || !is_a($oDate, 'Date') || !is_a($oCampaignExpiryDate, 'Date') || !is_a($oDeliveryLimitation, 'OA_Maintenance_Priority_DeliveryLimitation') || !is_array($aAdZones) || empty($aAdZones)) {
         OA::debug('- Invalid parameters in _getAdImpressions, skipping...', PEAR_LOG_ERR);
         return 0;
     }
     // This part must be run using the agency timezone
     $oStart = new Date($oDate);
     $oStart->convertTZ($this->currentTz);
     $oEnd = new Date($oCampaignExpiryDate);
     $oEnd->convertTZ($this->currentTz);
     if ($oDeliveryLimitation->deliveryBlocked($oStart) == true) {
         // The advertisement is not currently able to deliver, and so
         // no impressions should be allocated for this operation interval
         return 0;
     }
     // Get the cumulative associated zones forecasts for the previous week's
     // zone inventory forecasts, keyed by the operation interval ID
     $aCumulativeZoneForecast = $this->_getCumulativeZoneForecast($oAd->id, $aAdZones);
     // Get the total number of zone impressions remaining in which this
     // ad is capable of delivering (taking into account any operation
     // intervals where the ad is blocked)
     $totalAdLifetimeZoneImpressionsRemaining = $oDeliveryLimitation->getAdLifetimeZoneImpressionsRemaining($oStart, $oEnd, $aCumulativeZoneForecast);
     // Are there impressions forecast?
     if ($totalAdLifetimeZoneImpressionsRemaining == 0) {
         return 0;
     }
     // Get the current operation interval ID
     $currentOperationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID($oDate);
     // Scale the total required impressions for the ad over its lifetime
     // into the current operation interval forecast, relative to the total
     // zone-pattern based forecast for the remaining lifetime of the ad
     $scale = $aCumulativeZoneForecast[$currentOperationIntervalID] / $totalAdLifetimeZoneImpressionsRemaining;
     $impressions = $totalRequiredAdImpressions * $scale;
     return round($impressions);
 }
Beispiel #3
0
 /**
  * A method for obtaining the targeting statistics of an ad or placement
  * for a single day, where the data is summarised by operation interval.
  *
  * @param integer    $id    The ad or placement ID.
  * @param string     $type  Either "ad" or "placement".
  * @param PEAR::Date $oDate A date representing the day required.
  *
  * @return mixed Returns false in the event of incorrect input, or in the case
  *               of being unable to connect to the database, otherwise, returns
  *               an array of arrays:
  *
  *
  * array(
  *     [$operationIntervalId] => array(
  *                                  ['interval_start']             => PEAR::Date
  *                                  ['interval_end']               => PEAR::Date
  *                                  ['ad_required_impressions']    => integer
  *                                  ['ad_requested_impressions']   => integer
  *                                  ['ad_actual_impressions']      => integer
  *                                  ['zones_forecast_impressions'] => integer
  *                                  ['zones_actual_impressions']   => integer
  *                                  ['average']                    => integer
  *                               )
  *      .
  *      .
  *      .
  * )
  *
  * or:
  *
  * array(
  *     [$operationIntervalId] => array(
  *                                  ['interval_start']                  => PEAR::Date
  *                                  ['interval_end']                    => PEAR::Date
  *                                  ['placement_required_impressions']  => integer
  *                                  ['placement_requested_impressions'] => integer
  *                                  ['placement_actual_impressions']    => integer
  *                                  ['zones_forecast_impressions']      => integer
  *                                  ['zones_actual_impressions']        => integer
  *                                  ['average']                         => integer
  *                               )
  *      .
  *      .
  *      .
  * )
  *
  * For the ad or placement and day specified, returns an array for each
  * operation interval in the day, consisting of the operation interval start
  * and end dates, and the total number of impressions requested by the ad, or
  * all ads in the placement (for all zones the ads are linked to), as well as
  * the total number of impressions actually delivered by the ad, or all ads
  * in the placement (for all zones the ads are linked to).
  *
  * The individual ad/zone impressions requested values may need to be
  * calculated as an "averge" value, in the event that there are multiple,
  * differing values for an ad in a zone for an operation interval -- in
  * much the same way as is done in
  * OA_Dal_Maintenance_Priority::getPreviousAdDeliveryInfo() -- before
  * the total impressions requested value can be calculated.
  */
 function getDailyTargetingStatistics($id, $type, $oDate)
 {
     if (!$this->_testGetTargetingStatisticsDayParameters($id, $type, $oDate)) {
         return false;
     }
     // Ensure that, if a placement, the placement has advertisements
     $aAdIds = $this->_testGetTargetingStatisticsSpanPlacement($id, $type);
     if ($aAdIds === false) {
         return false;
     }
     // Prepare the results array
     $aResult = array();
     // Get a date for the start of the day
     $oStartDate = new Date();
     $oStartDate->copy($oDate);
     $oStartDate->setHour(0);
     $oStartDate->setMinute(0);
     $oStartDate->setSecond(0);
     // Get a date for the end of the day
     $oEndOfDayDate = new Date();
     $oEndOfDayDate->copy($oDate);
     $oEndOfDayDate->setHour(23);
     $oEndOfDayDate->setMinute(59);
     $oEndOfDayDate->setSecond(59);
     // Get the first operation interval of the day
     $aDates = OX_OperationInterval::convertDateToOperationIntervalStartAndEndDates($oStartDate);
     // Get dates to be used in date comparisons
     $oCompareDate = new Date();
     $oCompareDate->copy($aDates['start']);
     $oCompareEndDate = new Date();
     $oCompareEndDate->copy($oEndOfDayDate);
     while ($oCompareDate->before($oEndOfDayDate)) {
         // Get the operation interval ID
         $operationIntervalId = OX_OperationInterval::convertDateToOperationIntervalID($aDates['start']);
         // Get the results for this operation interval
         $aResult[$operationIntervalId] = $this->getOperationIntervalTargetingStatistics($aAdIds, $type, $aDates['start'], $aDates['end']);
         if ($aResult[$operationIntervalId] === false) {
             return false;
         }
         // Get the next operation interval dates
         $aDates = OX_OperationInterval::convertDateToNextOperationIntervalStartAndEndDates($aDates['start']);
         // Update the comparison dates
         $oCompareDate = new Date();
         $oCompareDate->copy($aDates['start']);
         $oCompareEndDate = new Date();
         $oCompareEndDate->copy($oEndOfDayDate);
     }
     return $aResult;
 }
 function _getOperationIntervalInfo(&$operationIntervalId, &$operationInterval, &$dateStart, &$dateEnd)
 {
     $date = new Date();
     $operationInterval = new OX_OperationInterval();
     $operationIntervalId = $operationInterval->convertDateToOperationIntervalID($date);
     $operationInterval = OX_OperationInterval::getOperationInterval();
     $aOperationIntervalDates = OX_OperationInterval::convertDateToOperationIntervalStartAndEndDates($date);
     $dateStart = DBC::makeLiteral($aOperationIntervalDates['start']->format(TIMESTAMP_FORMAT));
     $dateEnd = DBC::makeLiteral($aOperationIntervalDates['end']->format(TIMESTAMP_FORMAT));
 }
 /**
  * A method to test the main run() method.
  */
 function testRun()
 {
     $aConf =& $GLOBALS['_MAX']['CONF'];
     $aConf['maintenance']['operationInterval'] = 60;
     $oServiceLocator =& OA_ServiceLocator::instance();
     $oFactory = new OX_Dal_Maintenance_Statistics_Factory();
     $oDalMaintenanceStatsticsClassName = $oFactory->deriveClassName();
     // Test 1: Run, with the migration required but with no plugins installed
     $oNowDate = new Date('2008-08-28 09:01:00');
     $oServiceLocator->register('now', $oNowDate);
     $oMaintenanceStatistics = new OX_Maintenance_Statistics();
     $oMaintenanceStatistics->updateIntermediate = true;
     $oMaintenanceStatistics->oLastDateIntermediate = new Date('2008-08-28 07:59:59');
     $oMaintenanceStatistics->oUpdateIntermediateToDate = new Date('2008-08-28 08:59:59');
     Mock::generatePartial($oDalMaintenanceStatsticsClassName, 'MockOX_Dal_Maintenance_Statistics_Test_1', array('summariseBucketsRaw', 'summariseBucketsRawSupplementary', 'summariseBucketsAggregate', 'migrateRawRequests', 'migrateRawImpressions', 'migrateRawClicks'));
     $oDal = new MockOX_Dal_Maintenance_Statistics_Test_1($this);
     $oDal->expectNever('summariseBucketsRaw');
     $oDal->expectNever('summariseBucketsRawSupplementary');
     $oDal->expectNever('summariseBucketsAggregate');
     $oDal->expectNever('migrateRawRequests');
     $oDal->expectNever('migrateRawImpressions');
     $oDal->expectNever('migrateRawClicks');
     $oDal->OX_Dal_Maintenance_Statistics();
     $oServiceLocator->register('OX_Dal_Maintenance_Statistics', $oDal);
     $oSummariseIntermediate = new OX_Maintenance_Statistics_Task_MigrateBucketData();
     $oSummariseIntermediate->run();
     $oDal =& $oServiceLocator->get('OX_Dal_Maintenance_Statistics');
     $oDal->tally();
     // Create the "application_variable" table required for installing the plugin
     $oTables =& OA_DB_Table_Core::singleton();
     $oTables->createTable('application_variable');
     // Setup the default OpenX delivery logging plugin for the next test
     TestEnv::installPluginPackage('openXDeliveryLog', false);
     // Test 2: Run, with plugins installed, but with the migration not required
     $oNowDate = new Date('2008-08-28 09:01:00');
     $oServiceLocator->register('now', $oNowDate);
     $oMaintenanceStatistics = new OX_Maintenance_Statistics();
     $oMaintenanceStatistics->updateIntermediate = false;
     $oServiceLocator->register('Maintenance_Statistics_Controller', $oMaintenanceStatistics);
     Mock::generatePartial($oDalMaintenanceStatsticsClassName, 'MockOX_Dal_Maintenance_Statistics_Test_2', array('summariseBucketsRaw', 'summariseBucketsRawSupplementary', 'summariseBucketsAggregate', 'migrateRawRequests', 'migrateRawImpressions', 'migrateRawClicks'));
     $oDal = new MockOX_Dal_Maintenance_Statistics_Test_2($this);
     $oDal->expectNever('summariseBucketsRaw');
     $oDal->expectNever('summariseBucketsRawSupplementary');
     $oDal->expectNever('summariseBucketsAggregate');
     $oDal->expectNever('migrateRawRequests');
     $oDal->expectNever('migrateRawImpressions');
     $oDal->expectNever('migrateRawClicks');
     $oDal->OX_Dal_Maintenance_Statistics();
     $oServiceLocator->register('OX_Dal_Maintenance_Statistics', $oDal);
     $oSummariseIntermediate = new OX_Maintenance_Statistics_Task_MigrateBucketData();
     $oSummariseIntermediate->run();
     $oDal =& $oServiceLocator->get('OX_Dal_Maintenance_Statistics');
     $oDal->tally();
     // Test 3: Run, with plugins installed and with the migration required for a single
     //         operation interval
     $oNowDate = new Date('2008-08-28 09:01:00');
     $oServiceLocator->register('now', $oNowDate);
     $oMaintenanceStatistics = new OX_Maintenance_Statistics();
     $oMaintenanceStatistics->updateIntermediate = true;
     $oMaintenanceStatistics->oLastDateIntermediate = new Date('2008-08-28 07:59:59');
     $oMaintenanceStatistics->oUpdateIntermediateToDate = new Date('2008-08-28 08:59:59');
     $oServiceLocator->register('Maintenance_Statistics_Controller', $oMaintenanceStatistics);
     Mock::generatePartial($oDalMaintenanceStatsticsClassName, 'MockOX_Dal_Maintenance_Statistics_Test_3', array('summariseBucketsRaw', 'summariseBucketsRawSupplementary', 'summariseBucketsAggregate', 'migrateRawRequests', 'migrateRawImpressions', 'migrateRawClicks'));
     $oDal = new MockOX_Dal_Maintenance_Statistics_Test_3($this);
     $oComponent =& OX_Component::factory('deliveryLog', 'oxLogConversion', 'logConversion');
     $oStartDate = new Date('2008-08-28 07:59:59');
     $oStartDate->addSeconds(1);
     $oEndDate = new Date('2008-08-28 09:00:00');
     $oEndDate->subtractSeconds(1);
     $oDal->expectOnce('summariseBucketsRaw', array($aConf['table']['prefix'] . 'data_intermediate_ad_connection', $oComponent->getStatisticsMigration(), array('start' => $oStartDate, 'end' => $oEndDate)));
     $oComponent =& OX_Component::factory('deliveryLog', 'oxLogConversion', 'logConversionVariable');
     $oStartDate = new Date('2008-08-28 07:59:59');
     $oStartDate->addSeconds(1);
     $oEndDate = new Date('2008-08-28 09:00:00');
     $oEndDate->subtractSeconds(1);
     $oDal->expectOnce('summariseBucketsRawSupplementary', array($aConf['table']['prefix'] . 'data_intermediate_ad_variable_value', $oComponent->getStatisticsMigration(), array('start' => $oStartDate, 'end' => $oEndDate)));
     $aMap = array();
     $oComponent =& OX_Component::factory('deliveryLog', 'oxLogClick', 'logClick');
     $aMap[get_class($oComponent)] = $oComponent->getStatisticsMigration();
     $oComponent =& OX_Component::factory('deliveryLog', 'oxLogImpression', 'logImpression');
     $aMap[get_class($oComponent)] = $oComponent->getStatisticsMigration();
     $oComponent =& OX_Component::factory('deliveryLog', 'oxLogRequest', 'logRequest');
     $aMap[get_class($oComponent)] = $oComponent->getStatisticsMigration();
     $oStartDate = new Date('2008-08-28 07:59:59');
     $oStartDate->addSeconds(1);
     $oEndDate = new Date('2008-08-28 09:00:00');
     $oEndDate->subtractSeconds(1);
     $oDal->expectOnce('summariseBucketsAggregate', array($aConf['table']['prefix'] . 'data_intermediate_ad', $aMap, array('start' => $oStartDate, 'end' => $oEndDate), array('operation_interval' => '60', 'operation_interval_id' => OX_OperationInterval::convertDateToOperationIntervalID($oStartDate), 'interval_start' => "'2008-08-28 08:00:00'", 'interval_end' => "'2008-08-28 08:59:59'", 'creative_id' => 0, 'updated' => "'2008-08-28 09:01:00'")));
     $oDal->expectNever('migrateRawRequests');
     $oDal->expectNever('migrateRawImpressions');
     $oDal->expectNever('migrateRawClicks');
     $oDal->OX_Dal_Maintenance_Statistics();
     $oServiceLocator->register('OX_Dal_Maintenance_Statistics', $oDal);
     $oSummariseIntermediate = new OX_Maintenance_Statistics_Task_MigrateBucketData();
     $oSummariseIntermediate->run();
     $oDal =& $oServiceLocator->get('OX_Dal_Maintenance_Statistics');
     $oDal->tally();
     // Test 4: Run, with plugins installed and with the migration required for a single
     //         operation interval + migration of raw data set to occur
     $doApplication_variable = OA_Dal::factoryDO('application_variable');
     $doApplication_variable->name = 'mse_process_raw';
     $doApplication_variable->value = '1';
     $doApplication_variable->insert();
     $oNowDate = new Date('2008-08-28 09:01:00');
     $oServiceLocator->register('now', $oNowDate);
     $oMaintenanceStatistics = new OX_Maintenance_Statistics();
     $oMaintenanceStatistics->updateIntermediate = true;
     $oMaintenanceStatistics->oLastDateIntermediate = new Date('2008-08-28 07:59:59');
     $oMaintenanceStatistics->oUpdateIntermediateToDate = new Date('2008-08-28 08:59:59');
     $oServiceLocator->register('Maintenance_Statistics_Controller', $oMaintenanceStatistics);
     Mock::generatePartial($oDalMaintenanceStatsticsClassName, 'MockOX_Dal_Maintenance_Statistics_Test_4', array('summariseBucketsRaw', 'summariseBucketsRawSupplementary', 'summariseBucketsAggregate', 'migrateRawRequests', 'migrateRawImpressions', 'migrateRawClicks'));
     $oDal = new MockOX_Dal_Maintenance_Statistics_Test_4($this);
     $oComponent =& OX_Component::factory('deliveryLog', 'oxLogConversion', 'logConversion');
     $oStartDate = new Date('2008-08-28 07:59:59');
     $oStartDate->addSeconds(1);
     $oEndDate = new Date('2008-08-28 09:00:00');
     $oEndDate->subtractSeconds(1);
     $oDal->expectOnce('summariseBucketsRaw', array($aConf['table']['prefix'] . 'data_intermediate_ad_connection', $oComponent->getStatisticsMigration(), array('start' => $oStartDate, 'end' => $oEndDate)));
     $oComponent =& OX_Component::factory('deliveryLog', 'oxLogConversion', 'logConversionVariable');
     $oStartDate = new Date('2008-08-28 07:59:59');
     $oStartDate->addSeconds(1);
     $oEndDate = new Date('2008-08-28 09:00:00');
     $oEndDate->subtractSeconds(1);
     $oDal->expectOnce('summariseBucketsRawSupplementary', array($aConf['table']['prefix'] . 'data_intermediate_ad_variable_value', $oComponent->getStatisticsMigration(), array('start' => $oStartDate, 'end' => $oEndDate)));
     $aMap = array();
     $oComponent =& OX_Component::factory('deliveryLog', 'oxLogClick', 'logClick');
     $aMap[get_class($oComponent)] = $oComponent->getStatisticsMigration();
     $oComponent =& OX_Component::factory('deliveryLog', 'oxLogImpression', 'logImpression');
     $aMap[get_class($oComponent)] = $oComponent->getStatisticsMigration();
     $oComponent =& OX_Component::factory('deliveryLog', 'oxLogRequest', 'logRequest');
     $aMap[get_class($oComponent)] = $oComponent->getStatisticsMigration();
     $oStartDate = new Date('2008-08-28 07:59:59');
     $oStartDate->addSeconds(1);
     $oEndDate = new Date('2008-08-28 09:00:00');
     $oEndDate->subtractSeconds(1);
     $oDal->expectOnce('summariseBucketsAggregate', array($aConf['table']['prefix'] . 'data_intermediate_ad', $aMap, array('start' => $oStartDate, 'end' => $oEndDate), array('operation_interval' => '60', 'operation_interval_id' => OX_OperationInterval::convertDateToOperationIntervalID($oStartDate), 'interval_start' => "'2008-08-28 08:00:00'", 'interval_end' => "'2008-08-28 08:59:59'", 'creative_id' => 0, 'updated' => "'2008-08-28 09:01:00'")));
     $oDal->expectOnce('migrateRawRequests', array($oStartDate, $oEndDate));
     $oDal->expectOnce('migrateRawImpressions', array($oStartDate, $oEndDate));
     $oDal->expectOnce('migrateRawClicks', array($oStartDate, $oEndDate));
     $oDal->OX_Dal_Maintenance_Statistics();
     $oServiceLocator->register('OX_Dal_Maintenance_Statistics', $oDal);
     $oSummariseIntermediate = new OX_Maintenance_Statistics_Task_MigrateBucketData();
     $oSummariseIntermediate->run();
     $oDal =& $oServiceLocator->get('OX_Dal_Maintenance_Statistics');
     $oDal->tally();
     $doApplication_variable = OA_Dal::factoryDO('application_variable');
     $doApplication_variable->name = 'mse_process_raw';
     $doApplication_variable->value = '1';
     $doApplication_variable->find();
     $rows = $doApplication_variable->getRowCount();
     $this->assertEqual($rows, 0);
     // Test 5: Run, with plugins installed and with the migration required for multiple
     //         operation intervals
     $oNowDate = new Date('2008-08-28 11:01:00');
     $oServiceLocator->register('now', $oNowDate);
     $oMaintenanceStatistics = new OX_Maintenance_Statistics();
     $oMaintenanceStatistics->updateIntermediate = true;
     $oMaintenanceStatistics->oLastDateIntermediate = new Date('2008-08-28 07:59:59');
     $oMaintenanceStatistics->oUpdateIntermediateToDate = new Date('2008-08-28 10:59:59');
     $oServiceLocator->register('Maintenance_Statistics_Controller', $oMaintenanceStatistics);
     Mock::generatePartial($oDalMaintenanceStatsticsClassName, 'MockOX_Dal_Maintenance_Statistics_Test_5', array('summariseBucketsRaw', 'summariseBucketsRawSupplementary', 'summariseBucketsAggregate', 'migrateRawRequests', 'migrateRawImpressions', 'migrateRawClicks'));
     $oDal = new MockOX_Dal_Maintenance_Statistics_Test_5($this);
     $oDal->expectCallCount('summariseBucketsRaw', 3);
     $oDal->expectCallCount('summariseBucketsRawSupplementary', 3);
     $oDal->expectCallCount('summariseBucketsAggregate', 3);
     $oComponent =& OX_Component::factory('deliveryLog', 'oxLogConversion', 'logConversion');
     $oStartDate = new Date('2008-08-28 07:59:59');
     $oStartDate->addSeconds(1);
     $oEndDate = new Date('2008-08-28 09:00:00');
     $oEndDate->subtractSeconds(1);
     $oDal->expectAt(0, 'summariseBucketsRaw', array($aConf['table']['prefix'] . 'data_intermediate_ad_connection', $oComponent->getStatisticsMigration(), array('start' => $oStartDate, 'end' => $oEndDate)));
     $oStartDate = new Date('2008-08-28 08:59:59');
     $oStartDate->addSeconds(1);
     $oEndDate = new Date('2008-08-28 10:00:00');
     $oEndDate->subtractSeconds(1);
     $oDal->expectAt(1, 'summariseBucketsRaw', array($aConf['table']['prefix'] . 'data_intermediate_ad_connection', $oComponent->getStatisticsMigration(), array('start' => $oStartDate, 'end' => $oEndDate)));
     $oStartDate = new Date('2008-08-28 09:59:59');
     $oStartDate->addSeconds(1);
     $oEndDate = new Date('2008-08-28 11:00:00');
     $oEndDate->subtractSeconds(1);
     $oDal->expectAt(2, 'summariseBucketsRaw', array($aConf['table']['prefix'] . 'data_intermediate_ad_connection', $oComponent->getStatisticsMigration(), array('start' => $oStartDate, 'end' => $oEndDate)));
     $oComponent =& OX_Component::factory('deliveryLog', 'oxLogConversion', 'logConversionVariable');
     $oStartDate = new Date('2008-08-28 07:59:59');
     $oStartDate->addSeconds(1);
     $oEndDate = new Date('2008-08-28 09:00:00');
     $oEndDate->subtractSeconds(1);
     $oDal->expectAt(0, 'summariseBucketsRawSupplementary', array($aConf['table']['prefix'] . 'data_intermediate_ad_variable_value', $oComponent->getStatisticsMigration(), array('start' => $oStartDate, 'end' => $oEndDate)));
     $oStartDate = new Date('2008-08-28 08:59:59');
     $oStartDate->addSeconds(1);
     $oEndDate = new Date('2008-08-28 10:00:00');
     $oEndDate->subtractSeconds(1);
     $oDal->expectAt(1, 'summariseBucketsRawSupplementary', array($aConf['table']['prefix'] . 'data_intermediate_ad_variable_value', $oComponent->getStatisticsMigration(), array('start' => $oStartDate, 'end' => $oEndDate)));
     $oStartDate = new Date('2008-08-28 09:59:59');
     $oStartDate->addSeconds(1);
     $oEndDate = new Date('2008-08-28 11:00:00');
     $oEndDate->subtractSeconds(1);
     $oDal->expectAt(2, 'summariseBucketsRawSupplementary', array($aConf['table']['prefix'] . 'data_intermediate_ad_variable_value', $oComponent->getStatisticsMigration(), array('start' => $oStartDate, 'end' => $oEndDate)));
     $aMap = array();
     $oComponent =& OX_Component::factory('deliveryLog', 'oxLogClick', 'logClick');
     $aMap[get_class($oComponent)] = $oComponent->getStatisticsMigration();
     $oComponent =& OX_Component::factory('deliveryLog', 'oxLogImpression', 'logImpression');
     $aMap[get_class($oComponent)] = $oComponent->getStatisticsMigration();
     $oComponent =& OX_Component::factory('deliveryLog', 'oxLogRequest', 'logRequest');
     $aMap[get_class($oComponent)] = $oComponent->getStatisticsMigration();
     $oStartDate = new Date('2008-08-28 07:59:59');
     $oStartDate->addSeconds(1);
     $oEndDate = new Date('2008-08-28 09:00:00');
     $oEndDate->subtractSeconds(1);
     $oDal->expectAt(0, 'summariseBucketsAggregate', array($aConf['table']['prefix'] . 'data_intermediate_ad', $aMap, array('start' => $oStartDate, 'end' => $oEndDate), array('operation_interval' => '60', 'operation_interval_id' => OX_OperationInterval::convertDateToOperationIntervalID($oStartDate), 'interval_start' => "'2008-08-28 08:00:00'", 'interval_end' => "'2008-08-28 08:59:59'", 'creative_id' => 0, 'updated' => "'2008-08-28 11:01:00'")));
     $oStartDate = new Date('2008-08-28 08:59:59');
     $oStartDate->addSeconds(1);
     $oEndDate = new Date('2008-08-28 10:00:00');
     $oEndDate->subtractSeconds(1);
     $oDal->expectAt(1, 'summariseBucketsAggregate', array($aConf['table']['prefix'] . 'data_intermediate_ad', $aMap, array('start' => $oStartDate, 'end' => $oEndDate), array('operation_interval' => '60', 'operation_interval_id' => OX_OperationInterval::convertDateToOperationIntervalID($oStartDate), 'interval_start' => "'2008-08-28 09:00:00'", 'interval_end' => "'2008-08-28 09:59:59'", 'creative_id' => 0, 'updated' => "'2008-08-28 11:01:00'")));
     $oStartDate = new Date('2008-08-28 09:59:59');
     $oStartDate->addSeconds(1);
     $oEndDate = new Date('2008-08-28 11:00:00');
     $oEndDate->subtractSeconds(1);
     $oDal->expectAt(2, 'summariseBucketsAggregate', array($aConf['table']['prefix'] . 'data_intermediate_ad', $aMap, array('start' => $oStartDate, 'end' => $oEndDate), array('operation_interval' => '60', 'operation_interval_id' => OX_OperationInterval::convertDateToOperationIntervalID($oStartDate), 'interval_start' => "'2008-08-28 10:00:00'", 'interval_end' => "'2008-08-28 10:59:59'", 'creative_id' => 0, 'updated' => "'2008-08-28 11:01:00'")));
     $oDal->expectNever('migrateRawRequests');
     $oDal->expectNever('migrateRawImpressions');
     $oDal->expectNever('migrateRawClicks');
     $oDal->OX_Dal_Maintenance_Statistics();
     $oServiceLocator->register('OX_Dal_Maintenance_Statistics', $oDal);
     $oSummariseIntermediate = new OX_Maintenance_Statistics_Task_MigrateBucketData();
     $oSummariseIntermediate->run();
     $oDal =& $oServiceLocator->get('OX_Dal_Maintenance_Statistics');
     $oDal->tally();
     // Test 6: Run, with plugins installed and with the migration required for multiple
     //         operation intervals + migration of raw data set to occur
     $doApplication_variable = OA_Dal::factoryDO('application_variable');
     $doApplication_variable->name = 'mse_process_raw';
     $doApplication_variable->value = '1';
     $doApplication_variable->insert();
     $oNowDate = new Date('2008-08-28 11:01:00');
     $oServiceLocator->register('now', $oNowDate);
     $oMaintenanceStatistics = new OX_Maintenance_Statistics();
     $oMaintenanceStatistics->updateIntermediate = true;
     $oMaintenanceStatistics->oLastDateIntermediate = new Date('2008-08-28 07:59:59');
     $oMaintenanceStatistics->oUpdateIntermediateToDate = new Date('2008-08-28 10:59:59');
     $oServiceLocator->register('Maintenance_Statistics_Controller', $oMaintenanceStatistics);
     Mock::generatePartial($oDalMaintenanceStatsticsClassName, 'MockOX_Dal_Maintenance_Statistics_Test_6', array('summariseBucketsRaw', 'summariseBucketsRawSupplementary', 'summariseBucketsAggregate', 'migrateRawRequests', 'migrateRawImpressions', 'migrateRawClicks'));
     $oDal = new MockOX_Dal_Maintenance_Statistics_Test_6($this);
     $oDal->expectCallCount('summariseBucketsRaw', 3);
     $oDal->expectCallCount('summariseBucketsRawSupplementary', 3);
     $oDal->expectCallCount('summariseBucketsAggregate', 3);
     $oComponent =& OX_Component::factory('deliveryLog', 'oxLogConversion', 'logConversion');
     $oStartDate = new Date('2008-08-28 07:59:59');
     $oStartDate->addSeconds(1);
     $oEndDate = new Date('2008-08-28 09:00:00');
     $oEndDate->subtractSeconds(1);
     $oDal->expectAt(0, 'summariseBucketsRaw', array($aConf['table']['prefix'] . 'data_intermediate_ad_connection', $oComponent->getStatisticsMigration(), array('start' => $oStartDate, 'end' => $oEndDate)));
     $oStartDate = new Date('2008-08-28 08:59:59');
     $oStartDate->addSeconds(1);
     $oEndDate = new Date('2008-08-28 10:00:00');
     $oEndDate->subtractSeconds(1);
     $oDal->expectAt(1, 'summariseBucketsRaw', array($aConf['table']['prefix'] . 'data_intermediate_ad_connection', $oComponent->getStatisticsMigration(), array('start' => $oStartDate, 'end' => $oEndDate)));
     $oStartDate = new Date('2008-08-28 09:59:59');
     $oStartDate->addSeconds(1);
     $oEndDate = new Date('2008-08-28 11:00:00');
     $oEndDate->subtractSeconds(1);
     $oDal->expectAt(2, 'summariseBucketsRaw', array($aConf['table']['prefix'] . 'data_intermediate_ad_connection', $oComponent->getStatisticsMigration(), array('start' => $oStartDate, 'end' => $oEndDate)));
     $oComponent =& OX_Component::factory('deliveryLog', 'oxLogConversion', 'logConversionVariable');
     $oStartDate = new Date('2008-08-28 07:59:59');
     $oStartDate->addSeconds(1);
     $oEndDate = new Date('2008-08-28 09:00:00');
     $oEndDate->subtractSeconds(1);
     $oDal->expectAt(0, 'summariseBucketsRawSupplementary', array($aConf['table']['prefix'] . 'data_intermediate_ad_variable_value', $oComponent->getStatisticsMigration(), array('start' => $oStartDate, 'end' => $oEndDate)));
     $oStartDate = new Date('2008-08-28 08:59:59');
     $oStartDate->addSeconds(1);
     $oEndDate = new Date('2008-08-28 10:00:00');
     $oEndDate->subtractSeconds(1);
     $oDal->expectAt(1, 'summariseBucketsRawSupplementary', array($aConf['table']['prefix'] . 'data_intermediate_ad_variable_value', $oComponent->getStatisticsMigration(), array('start' => $oStartDate, 'end' => $oEndDate)));
     $oStartDate = new Date('2008-08-28 09:59:59');
     $oStartDate->addSeconds(1);
     $oEndDate = new Date('2008-08-28 11:00:00');
     $oEndDate->subtractSeconds(1);
     $oDal->expectAt(2, 'summariseBucketsRawSupplementary', array($aConf['table']['prefix'] . 'data_intermediate_ad_variable_value', $oComponent->getStatisticsMigration(), array('start' => $oStartDate, 'end' => $oEndDate)));
     $aMap = array();
     $oComponent =& OX_Component::factory('deliveryLog', 'oxLogClick', 'logClick');
     $aMap[get_class($oComponent)] = $oComponent->getStatisticsMigration();
     $oComponent =& OX_Component::factory('deliveryLog', 'oxLogImpression', 'logImpression');
     $aMap[get_class($oComponent)] = $oComponent->getStatisticsMigration();
     $oComponent =& OX_Component::factory('deliveryLog', 'oxLogRequest', 'logRequest');
     $aMap[get_class($oComponent)] = $oComponent->getStatisticsMigration();
     $oStartDate = new Date('2008-08-28 07:59:59');
     $oStartDate->addSeconds(1);
     $oEndDate = new Date('2008-08-28 09:00:00');
     $oEndDate->subtractSeconds(1);
     $oDal->expectAt(0, 'summariseBucketsAggregate', array($aConf['table']['prefix'] . 'data_intermediate_ad', $aMap, array('start' => $oStartDate, 'end' => $oEndDate), array('operation_interval' => '60', 'operation_interval_id' => OX_OperationInterval::convertDateToOperationIntervalID($oStartDate), 'interval_start' => "'2008-08-28 08:00:00'", 'interval_end' => "'2008-08-28 08:59:59'", 'creative_id' => 0, 'updated' => "'2008-08-28 11:01:00'")));
     $oStartDate = new Date('2008-08-28 08:59:59');
     $oStartDate->addSeconds(1);
     $oEndDate = new Date('2008-08-28 10:00:00');
     $oEndDate->subtractSeconds(1);
     $oDal->expectAt(1, 'summariseBucketsAggregate', array($aConf['table']['prefix'] . 'data_intermediate_ad', $aMap, array('start' => $oStartDate, 'end' => $oEndDate), array('operation_interval' => '60', 'operation_interval_id' => OX_OperationInterval::convertDateToOperationIntervalID($oStartDate), 'interval_start' => "'2008-08-28 09:00:00'", 'interval_end' => "'2008-08-28 09:59:59'", 'creative_id' => 0, 'updated' => "'2008-08-28 11:01:00'")));
     $oStartDate = new Date('2008-08-28 09:59:59');
     $oStartDate->addSeconds(1);
     $oEndDate = new Date('2008-08-28 11:00:00');
     $oEndDate->subtractSeconds(1);
     $oDal->expectAt(2, 'summariseBucketsAggregate', array($aConf['table']['prefix'] . 'data_intermediate_ad', $aMap, array('start' => $oStartDate, 'end' => $oEndDate), array('operation_interval' => '60', 'operation_interval_id' => OX_OperationInterval::convertDateToOperationIntervalID($oStartDate), 'interval_start' => "'2008-08-28 10:00:00'", 'interval_end' => "'2008-08-28 10:59:59'", 'creative_id' => 0, 'updated' => "'2008-08-28 11:01:00'")));
     $oStartDate = new Date('2008-08-28 07:59:59');
     $oStartDate->addSeconds(1);
     $oEndDate = new Date('2008-08-28 09:00:00');
     $oEndDate->subtractSeconds(1);
     $oDal->expectAt(0, 'migrateRawRequests', array($oStartDate, $oEndDate));
     $oDal->expectAt(0, 'migrateRawImpressions', array($oStartDate, $oEndDate));
     $oDal->expectAt(0, 'migrateRawClicks', array($oStartDate, $oEndDate));
     $oStartDate = new Date('2008-08-28 08:59:59');
     $oStartDate->addSeconds(1);
     $oEndDate = new Date('2008-08-28 10:00:00');
     $oEndDate->subtractSeconds(1);
     $oDal->expectAt(1, 'migrateRawRequests', array($oStartDate, $oEndDate));
     $oDal->expectAt(1, 'migrateRawImpressions', array($oStartDate, $oEndDate));
     $oDal->expectAt(1, 'migrateRawClicks', array($oStartDate, $oEndDate));
     $oStartDate = new Date('2008-08-28 09:59:59');
     $oStartDate->addSeconds(1);
     $oEndDate = new Date('2008-08-28 11:00:00');
     $oEndDate->subtractSeconds(1);
     $oDal->expectAt(2, 'migrateRawRequests', array($oStartDate, $oEndDate));
     $oDal->expectAt(2, 'migrateRawImpressions', array($oStartDate, $oEndDate));
     $oDal->expectAt(2, 'migrateRawClicks', array($oStartDate, $oEndDate));
     $oDal->OX_Dal_Maintenance_Statistics();
     $oServiceLocator->register('OX_Dal_Maintenance_Statistics', $oDal);
     $oSummariseIntermediate = new OX_Maintenance_Statistics_Task_MigrateBucketData();
     $oSummariseIntermediate->run();
     $oDal =& $oServiceLocator->get('OX_Dal_Maintenance_Statistics');
     $oDal->tally();
     $doApplication_variable = OA_Dal::factoryDO('application_variable');
     $doApplication_variable->name = 'mse_process_raw';
     $doApplication_variable->value = '1';
     $doApplication_variable->find();
     $rows = $doApplication_variable->getRowCount();
     $this->assertEqual($rows, 0);
     // Uninstall the installed plugins
     TestEnv::uninstallPluginPackage('openXDeliveryLog', false);
     // Reset the testing environment
     TestEnv::restoreEnv();
 }
 /**
  * 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();
 }
 /**
  * A private method to convert the ZIF update type from _getUpdateTypeRequired() into
  * a range of operation intervals where all zones require their ZIF values to be updated.
  *
  * @access private
  * @param mixed $type The update type required. Possible values are the same as
  *                    those returned from the
  *                    {@link OA_Maintenance_Priority_AdServer_Task_ForecastZoneImpressions::getUpdateTypeRequired()}
  *                    method.
  * @return array An array of hashes where keys are operation interval IDs, and
  *               values are PEAR Dates. One element in the array indicates a
  *               contiguous range, two elements indicate a non-contiguous range.
  */
 function _getOperationIntervalRanges($type)
 {
     // Initialise result array
     $aResult = array();
     switch (true) {
         case is_bool($type) && $type === false:
             // Update none, return an empty array
             return $aResult;
         case is_bool($type) && $type === true:
             // Update all - need one week's worth of operation intervals up until the end
             // of the operation interval *after* the one that statistics have been updated
             // to, as we need to predict one interval ahead of now
             $oStatsDates = OX_OperationInterval::convertDateToNextOperationIntervalStartAndEndDates($this->oDateNow);
             $oStartDate = new Date();
             $oStartDate->copy($oStatsDates['start']);
             $oStartDate->subtractSeconds(SECONDS_PER_WEEK);
             $startId = OX_OperationInterval::convertDateToOperationIntervalID($oStartDate);
             $totalIntervals = OX_OperationInterval::operationIntervalsPerWeek();
             break;
         case is_array($type) && $type[0] < $type[1]:
             // A contiguous (ie. inter-week) range, where the first operation interval
             // ID is the lower bound, and the second operation interval ID is the upper
             // The start operation interval ID is the operation interval ID right after
             // the operation interval ID that priority was updated to (ie. $type[0])
             $aDates = OX_OperationInterval::convertDateToNextOperationIntervalStartAndEndDates($this->oPriorityUpdatedToDate);
             $oStartDate = $aDates['start'];
             $startId = OX_OperationInterval::nextOperationIntervalID($type[0], 1);
             $totalIntervals = $type[1] - $type[0];
             break;
         case is_array($type) && $type[0] > $type[1]:
             // A non-contiguous range, so calculate as above, but use the first operation
             // interval ID as the upper bound, and the second operation interval ID as the
             // lower bound in the proceeding week
             // The start operation interval ID is the operation interval ID right after
             // the operation interval ID that priority was updated to (ie. $type[0])
             $aDates = OX_OperationInterval::convertDateToNextOperationIntervalStartAndEndDates($this->oPriorityUpdatedToDate);
             $oStartDate = $aDates['start'];
             $startId = OX_OperationInterval::nextOperationIntervalID($type[0], 1);
             $totalIntervals = OX_OperationInterval::operationIntervalsPerWeek() - $type[0] + $type[1];
             break;
         default:
             OA::debug('OA_Maintenance_Priority_AdServer_Task_ForecastZoneImpressions::getOperationIntRangeByType() called with unexpected type, exiting', PEAR_LOG_CRIT);
             exit;
     }
     // Build the update range array
     $aRange = array();
     $totalIntervalPerWeek = OX_OperationInterval::operationIntervalsPerWeek();
     for ($x = $startId, $y = 0; $y < $totalIntervals; $x++, $y++) {
         if ($x == $totalIntervalPerWeek) {
             $x = 0;
         }
         $aDates = array();
         $aDates['start'] = new Date($oStartDate);
         //->format('%Y-%m-%d %H:%M:%S');
         $oEndDate = new Date();
         $oEndDate->copy($oStartDate);
         $oEndDate->addSeconds(OX_OperationInterval::secondsPerOperationInterval() - 1);
         $aDates['end'] = $oEndDate;
         //->format('%Y-%m-%d %H:%M:%S');
         unset($oEndDate);
         $aRange[$x] = $aDates;
         $oStartDate->addSeconds(OX_OperationInterval::secondsPerOperationInterval());
     }
     // Is the update range array a contiguous (inter-weeek) range?
     if (array_key_exists($totalIntervalPerWeek - 1, $aRange) && array_key_exists(0, $aRange)) {
         // The range contains the first and the last operation interval IDs, is the
         // last date before the first date?
         $oFirstIntervalStartDate = new Date($aRange[0]['start']);
         $oLastIntervalStartDate = new Date($aRange[$totalIntervalPerWeek - 1]['start']);
         if ($oLastIntervalStartDate->before($oFirstIntervalStartDate)) {
             // It's a non-contiguous range, so split into two ranges
             $aRange1 = array();
             $aRange2 = array();
             for ($x = $startId; $x < $totalIntervalPerWeek; $x++) {
                 $aRange1[$x] = $aRange[$x];
             }
             for ($x = 0; $x < $startId; $x++) {
                 if (isset($aRange[$x])) {
                     $aRange2[$x] = $aRange[$x];
                 }
             }
             $aResult[] = $aRange1;
             $aResult[] = $aRange2;
             return $aResult;
         }
     }
     $aResult[] = $aRange;
     return $aResult;
 }
 /**
  * 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();
 }
 /**
  * Method to test the updatePriorities method.
  *
  * Test 1: Test with no Date registered in the service locator, ensure false returned.
  * Test 2: Test with no data in the database, ensure data is correctly stored.
  * Test 3: Test with previous test data in the database, ensure data is correctly stored.
  * Test 4: Test with an obscene number of items, and ensure that the packet size is
  *         not exceeded (no asserts, test suite will simply fail if unable to work).
  */
 function testUpdatePriorities()
 {
     /**
      * @TODO Locate where clean up doesn't happen before this test, and fix!
      */
     TestEnv::restoreEnv();
     $conf = $GLOBALS['_MAX']['CONF'];
     $oDbh =& OA_DB::singleton();
     $oMaxDalMaintenance = new OA_Dal_Maintenance_Priority();
     // Insert the data into the ad_zone_assoc table, as an ad is linked to a zone
     $this->_generateTestData();
     // Test 1
     $oServiceLocator =& OA_ServiceLocator::instance();
     $oServiceLocator->remove('now');
     $aData = array(array('ads' => array(array('ad_id' => $this->aIds['ad'], 'zone_id' => $this->aIds['zone'], 'required_impressions' => '1000', 'requested_impressions' => '1000', 'priority' => '0.45', 'priority_factor' => null, 'priority_factor_limited' => false, 'past_zone_traffic_fraction' => null))));
     $result = $oMaxDalMaintenance->updatePriorities($aData);
     $this->assertFalse($result);
     // Test 2
     $oDate = new Date();
     $oServiceLocator->register('now', $oDate);
     $result = $oMaxDalMaintenance->updatePriorities($aData);
     $this->assertTrue($result);
     $query = "\n            SELECT\n                ad_id,\n                zone_id,\n                priority\n            FROM\n                " . $oDbh->quoteIdentifier($conf['table']['prefix'] . $conf['table']['ad_zone_assoc'], true) . "\n            WHERE\n                ad_id = {$this->aIds['ad']} AND zone_id = {$this->aIds['zone']}";
     $rc = $oDbh->query($query);
     $aRow = $rc->fetchRow();
     $this->assertEqual($aRow['ad_id'], $this->aIds['ad']);
     $this->assertEqual($aRow['zone_id'], $this->aIds['zone']);
     $this->assertEqual($aRow['priority'], 0.45);
     $query = "\n            SELECT\n                operation_interval,\n                operation_interval_id,\n                interval_start,\n                interval_end,\n                ad_id,\n                zone_id,\n                required_impressions,\n                requested_impressions,\n                priority,\n                priority_factor,\n                priority_factor_limited,\n                past_zone_traffic_fraction,\n                created,\n                created_by,\n                expired,\n                expired_by\n            FROM\n                " . $oDbh->quoteIdentifier($conf['table']['prefix'] . $conf['table']['data_summary_ad_zone_assoc'], true) . "\n            WHERE\n                ad_id = {$this->aIds['ad']}";
     $rc = $oDbh->query($query);
     $aRow = $rc->fetchRow();
     $currentOperationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID($oDate);
     $aDates = OX_OperationInterval::convertDateToOperationIntervalStartAndEndDates($oDate);
     $this->assertEqual($aRow['operation_interval'], $conf['maintenance']['operationInterval']);
     $this->assertEqual($aRow['operation_interval_id'], $currentOperationIntervalID);
     $this->assertEqual($aRow['interval_start'], $aDates['start']->format('%Y-%m-%d %H:%M:%S'));
     $this->assertEqual($aRow['interval_end'], $aDates['end']->format('%Y-%m-%d %H:%M:%S'));
     $this->assertEqual($aRow['ad_id'], $this->aIds['ad']);
     $this->assertEqual($aRow['zone_id'], $this->aIds['zone']);
     $this->assertEqual($aRow['required_impressions'], 1000);
     $this->assertEqual($aRow['requested_impressions'], 1000);
     $this->assertEqual($aRow['priority'], 0.45);
     $this->assertNull($aRow['priority_factor']);
     $this->assertFalse($aRow['priority_factor_limited']);
     $this->assertNull($aRow['past_zone_traffic_fraction']);
     $this->assertEqual($aRow['created'], $oDate->format('%Y-%m-%d %H:%M:%S'));
     $this->assertEqual($aRow['created_by'], 0);
     $this->assertNull($aRow['expired']);
     $this->assertNull($aRow['expired_by']);
     // Test 3
     $aData = array(array('ads' => array(array('ad_id' => $this->aIds['ad'], 'zone_id' => $this->aIds['zone'], 'required_impressions' => 2000, 'requested_impressions' => 2000, 'priority' => 0.9, 'priority_factor' => 0.1, 'priority_factor_limited' => false, 'past_zone_traffic_fraction' => 0.99), array('ad_id' => $this->aIds['ad'] + 1, 'zone_id' => $this->aIds['ad'] + 1, 'required_impressions' => 500, 'requested_impressions' => 500, 'priority' => 0.1, 'priority_factor' => 0.2, 'priority_factor_limited' => true, 'past_zone_traffic_fraction' => 0.45))));
     $oOldDate = new Date();
     $oOldDate->copy($oDate);
     $oDate = new Date();
     $oServiceLocator->register('now', $oDate);
     $result = $oMaxDalMaintenance->updatePriorities($aData);
     $this->assertTrue($result);
     $query = "\n            SELECT\n                ad_id,\n                zone_id,\n                priority\n            FROM\n                " . $oDbh->quoteIdentifier($conf['table']['prefix'] . $conf['table']['ad_zone_assoc'], true) . "\n            WHERE\n                ad_id = {$this->aIds['ad']} AND zone_id = {$this->aIds['zone']}";
     $rc = $oDbh->query($query);
     $aRow = $rc->fetchRow();
     $this->assertEqual($aRow['ad_id'], $this->aIds['ad']);
     $this->assertEqual($aRow['zone_id'], $this->aIds['zone']);
     $this->assertEqual($aRow['priority'], 0.9);
     $query = "\n            SELECT\n                operation_interval,\n                operation_interval_id,\n                interval_start,\n                interval_end,\n                ad_id,\n                zone_id,\n                required_impressions,\n                requested_impressions,\n                priority,\n                priority_factor,\n                priority_factor_limited,\n                past_zone_traffic_fraction,\n                created,\n                created_by,\n                expired,\n                expired_by\n            FROM\n                " . $oDbh->quoteIdentifier($conf['table']['prefix'] . $conf['table']['data_summary_ad_zone_assoc'], true) . "\n            WHERE\n                ad_id = {$this->aIds['ad']}\n                AND expired IS NOT NULL";
     $rc = $oDbh->query($query);
     $aRow = $rc->fetchRow();
     $currentOperationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID($oOldDate);
     $aDates = OX_OperationInterval::convertDateToOperationIntervalStartAndEndDates($oOldDate);
     $this->assertEqual($aRow['operation_interval'], $conf['maintenance']['operationInterval']);
     $this->assertEqual($aRow['operation_interval_id'], $currentOperationIntervalID);
     $this->assertEqual($aRow['interval_start'], $aDates['start']->format('%Y-%m-%d %H:%M:%S'));
     $this->assertEqual($aRow['interval_end'], $aDates['end']->format('%Y-%m-%d %H:%M:%S'));
     $this->assertEqual($aRow['ad_id'], $this->aIds['ad']);
     $this->assertEqual($aRow['zone_id'], $this->aIds['ad']);
     $this->assertEqual($aRow['required_impressions'], 1000);
     $this->assertEqual($aRow['requested_impressions'], 1000);
     $this->assertEqual($aRow['priority'], 0.45);
     $this->assertNull($aRow['priority_factor']);
     $this->assertFalse($aRow['priority_factor_limited']);
     $this->assertNull($aRow['past_zone_traffic_fraction']);
     $this->assertEqual($aRow['created'], $oOldDate->format('%Y-%m-%d %H:%M:%S'));
     $this->assertEqual($aRow['created_by'], 0);
     $this->assertEqual($aRow['expired'], $oDate->format('%Y-%m-%d %H:%M:%S'));
     $this->assertEqual($aRow['expired_by'], 0);
     $query = "\n            SELECT\n                operation_interval,\n                operation_interval_id,\n                interval_start,\n                interval_end,\n                ad_id,\n                zone_id,\n                required_impressions,\n                requested_impressions,\n                priority,\n                priority_factor,\n                priority_factor_limited,\n                past_zone_traffic_fraction,\n                created,\n                created_by,\n                expired,\n                expired_by\n            FROM\n                " . $oDbh->quoteIdentifier($conf['table']['prefix'] . $conf['table']['data_summary_ad_zone_assoc'], true) . "\n            WHERE\n                ad_id = {$this->aIds['ad']}\n                AND expired IS NULL";
     $rc = $oDbh->query($query);
     $aRow = $rc->fetchRow();
     $currentOperationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID($oDate);
     $aDates = OX_OperationInterval::convertDateToOperationIntervalStartAndEndDates($oDate);
     $this->assertEqual($aRow['operation_interval'], $conf['maintenance']['operationInterval']);
     $this->assertEqual($aRow['operation_interval_id'], $currentOperationIntervalID);
     $this->assertEqual($aRow['interval_start'], $aDates['start']->format('%Y-%m-%d %H:%M:%S'));
     $this->assertEqual($aRow['interval_end'], $aDates['end']->format('%Y-%m-%d %H:%M:%S'));
     $this->assertEqual($aRow['ad_id'], $this->aIds['ad']);
     $this->assertEqual($aRow['zone_id'], $this->aIds['ad']);
     $this->assertEqual($aRow['required_impressions'], 2000);
     $this->assertEqual($aRow['requested_impressions'], 2000);
     $this->assertEqual($aRow['priority'], 0.9);
     $this->assertEqual($aRow['priority_factor'], 0.1);
     $this->assertFalse($aRow['priority_factor_limited']);
     $this->assertEqual($aRow['past_zone_traffic_fraction'], 0.99);
     $this->assertEqual($aRow['created'], $oDate->format('%Y-%m-%d %H:%M:%S'));
     $this->assertEqual($aRow['created_by'], 0);
     $this->assertNull($aRow['expired']);
     $this->assertNull($aRow['expired_by']);
     $query = "\n            SELECT\n                operation_interval,\n                operation_interval_id,\n                interval_start,\n                interval_end,\n                ad_id,\n                zone_id,\n                required_impressions,\n                requested_impressions,\n                priority,\n                priority_factor,\n                priority_factor_limited,\n                past_zone_traffic_fraction,\n                created,\n                created_by,\n                expired,\n                expired_by\n            FROM\n                " . $oDbh->quoteIdentifier($conf['table']['prefix'] . $conf['table']['data_summary_ad_zone_assoc'], true) . "\n            WHERE\n                ad_id = " . ($this->aIds['ad'] + 1);
     $rc = $oDbh->query($query);
     $aRow = $rc->fetchRow();
     $currentOperationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID($oDate);
     $aDates = OX_OperationInterval::convertDateToOperationIntervalStartAndEndDates($oDate);
     $this->assertEqual($aRow['operation_interval'], $conf['maintenance']['operationInterval']);
     $this->assertEqual($aRow['operation_interval_id'], $currentOperationIntervalID);
     $this->assertEqual($aRow['interval_start'], $aDates['start']->format('%Y-%m-%d %H:%M:%S'));
     $this->assertEqual($aRow['interval_end'], $aDates['end']->format('%Y-%m-%d %H:%M:%S'));
     $this->assertEqual($aRow['ad_id'], $this->aIds['ad'] + 1);
     $this->assertEqual($aRow['zone_id'], $this->aIds['ad'] + 1);
     $this->assertEqual($aRow['required_impressions'], 500);
     $this->assertEqual($aRow['requested_impressions'], 500);
     $this->assertEqual($aRow['priority'], 0.1);
     $this->assertEqual($aRow['priority_factor'], 0.2);
     $this->assertTrue($aRow['priority_factor_limited']);
     $this->assertEqual($aRow['past_zone_traffic_fraction'], 0.45);
     $this->assertEqual($aRow['created'], $oDate->format('%Y-%m-%d %H:%M:%S'));
     $this->assertEqual($aRow['created_by'], 0);
     $this->assertNull($aRow['expired']);
     $this->assertNull($aRow['expired_by']);
     // Test 4
     $aData = array();
     for ($i = 1; $i < 5000; $i++) {
         $aData[$i] = array('ads' => array(array('ad_id' => $i, 'zone_id' => $i, 'required_impressions' => 2000, 'requested_impressions' => 2000, 'priority' => 0.9, 'priority_factor' => 0.1, 'priority_factor_limited' => false, 'past_zone_traffic_fraction' => 0.99)));
     }
     $oOldDate = new Date();
     $oOldDate->copy($oDate);
     $oDate = new Date();
     $oServiceLocator->register('now', $oDate);
     $result = $oMaxDalMaintenance->updatePriorities($aData);
     TestEnv::restoreEnv('dropTmpTables');
 }
 /**
  * A method to obtain the sum of the zone forecast impression value, for all the zones
  * an advertisement is linked to, cloned out over the advertisement's entire remaining
  * lifetime in the campaign, with any blocked operation intervals removed.
  *
  * Requires that the getActiveAdOperationIntervals() method have previously been
  * called to function correctly.
  *
  * @param PEAR::Date $oNowDate The current date.
  * @param PEAR::Date $oEndDate The end date of the campaign. Note that if the end
  *                             date supplied is not at the end of a day, it will be
  *                             converted to be treated as such.
  * @param array $aCumulativeZoneForecast The cumulative forecast impressions, indexed
  *                                       by operation interval ID, of all the zones the
  *                                       advertisement is linked to.
  *                  array(
  *                      [operation_interval_id] => forecast_impressions,
  *                      [operation_interval_id] => forecast_impressions
  *                                  .
  *                                  .
  *                                  .
  *                  )
  * @return integer The ad's total remaining zone impression forecast for all zone for
  *                 the remaining life of the ad.
  */
 function getAdLifetimeZoneImpressionsRemaining($oNowDate, $oEndDate, $aCumulativeZoneForecast)
 {
     $totalAdLifetimeZoneImpressionsRemaining = 0;
     // Test the parameters, if invalid, return zero
     if (!is_a($oNowDate, 'date') || !is_a($oEndDate, 'date') || !is_array($aCumulativeZoneForecast) || count($aCumulativeZoneForecast) != OX_OperationInterval::operationIntervalsPerWeek()) {
         OA::debug('  - Invalid parameters to getAdLifetimeZoneImpressionsRemaining, returning 0', PEAR_LOG_ERR);
         return $totalAdLifetimeZoneImpressionsRemaining;
     }
     // Ensure that the end of campaign date is at the end of the day
     $oEndDateCopy = new Date($oEndDate);
     $oEndDateCopy->setHour(23);
     $oEndDateCopy->setMinute(59);
     $oEndDateCopy->setSecond(59);
     // Ensure that the $aCumulativeZoneForecast array is sorted by key, so that it can
     // be accessed by array_slice, regardless of the order that the forecast data was added
     // to the array
     ksort($aCumulativeZoneForecast);
     // Step 1: Calculate the sum of the forecast values from "now" until the end of "today"
     $aDates = OX_OperationInterval::convertDateToOperationIntervalStartAndEndDates($oNowDate);
     $oEndOfToday = new Date($aDates['start']);
     $oEndOfToday->setTZ($oEndDate->tz);
     $oEndOfToday->setHour(23);
     $oEndOfToday->setMinute(59);
     $oEndOfToday->setSecond(59);
     $oStart = $aDates['start'];
     while ($oStart->before($oEndOfToday)) {
         // Find the Operation Interval ID for this Operation Interval
         $operationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID($oStart);
         // As iteration over every OI is required anyway, test to see if
         // the ad is blocked in this OI; if not, add the forecast values to the
         // running total
         if (empty($this->aBlockedOperationIntervalDates[$oStart->format('%Y-%m-%d %H:%M:%S')])) {
             $totalAdLifetimeZoneImpressionsRemaining += $aCumulativeZoneForecast[$operationIntervalID];
         }
         // Go to the next operation interval in "today"
         $oStart = OX_OperationInterval::addOperationIntervalTimeSpan($oStart);
     }
     // Step 2: Calculate how many times each day of the week occurs between the end of
     //         "today" (i.e. starting "tomorrow morning") and the last day the ad can run
     $aDays = array();
     $oStartOfTomorrow = new Date($oEndOfToday);
     $oStartOfTomorrow->addSeconds(1);
     $oTempDate = new Date();
     $oTempDate->copy($oStartOfTomorrow);
     $aDates = OX_OperationInterval::convertDateToOperationIntervalStartAndEndDates($oTempDate);
     while ($aDates['start']->before($oEndDateCopy)) {
         // Increase the count for this day of the week
         $aDays[$aDates['start']->getDayOfWeek()]++;
         // Go to the next day
         $oTempDate->addSeconds(SECONDS_PER_DAY);
         $aDates = OX_OperationInterval::convertDateToOperationIntervalStartAndEndDates($oTempDate);
     }
     // Step 3: For every possible day of the week (assuming that day of the week is in the
     //         ad's remaining lifetime), calculate the sum of the forecast values for every
     //         operation interval in that day
     if (!empty($aDays)) {
         $operationIntervalsPerDay = OX_OperationInterval::operationIntervalsPerDay();
         $oTempDate = new Date($oStartOfTomorrow);
         $aDates = OX_OperationInterval::convertDateToOperationIntervalStartAndEndDates($oTempDate);
         for ($counter = 0; $counter < 7; $counter++) {
             // Are there any instances of this day in the campaign?
             if ($aDays[$oTempDate->getDayOfWeek()] > 0) {
                 // Calculate the sum of the zone forecasts for this day of week
                 $aDates = OX_OperationInterval::convertDateToOperationIntervalStartAndEndDates($oTempDate);
                 $dayStartOperationIntervalId = OX_OperationInterval::convertDateToOperationIntervalID($aDates['start']);
                 $aDayCumulativeZoneForecast = array_slice($aCumulativeZoneForecast, $dayStartOperationIntervalId, $operationIntervalsPerDay);
                 $forecastSum = array_sum($aDayCumulativeZoneForecast);
                 // Multiply this day's forecast sum value by the number of times this
                 // day of week appears in the remainder of the campaign and add the
                 // value to the running total
                 $totalAdLifetimeZoneImpressionsRemaining += $forecastSum * $aDays[$oTempDate->getDayOfWeek()];
             }
             // Go to the next day
             $oTempDate->addSeconds(SECONDS_PER_DAY);
         }
     }
     // Step 4: Subtract any blocked interval values
     if ($this->blockedOperationIntervalCount > 0) {
         OA::debug("      - Subtracting {$this->blockedOperationIntervalCount} blocked intervals", PEAR_LOG_DEBUG);
         foreach ($this->aBlockedOperationIntervalDates as $aDates) {
             if ($aDates['start']->after($oEndOfToday)) {
                 $blockedOperationInvervalID = OX_OperationInterval::convertDateToOperationIntervalID($aDates['start']);
                 $totalAdLifetimeZoneImpressionsRemaining -= $aCumulativeZoneForecast[$blockedOperationInvervalID];
             }
         }
     }
     // Return the calculated value
     return $totalAdLifetimeZoneImpressionsRemaining;
 }
 /**
  * A method to test the getAdLifetimeZoneImpressionsRemaining() method.
  *
  * Test 1: Test with invalid parameters, and ensure that zero is returned.
  * Test 2: Test with equal start and end dates, and ensure just that OI's
  *         data is returned.
  * Test 3: Test with a small range of dates in one week, that the correct
  *         sum is returned.
  * Test 4: Test with a small range of dates over three days, covering two
  *         weeks, and ensure that the correct result is returned.
  * Test 5: Test with a limitation that blocks less than 50% of the remaining
  *         range, and ensure that the correct result is returned.
  * Test 6: Test with a limitation that blocks more than 50% of the remaining
  *         range, and ensure that the correct result is returned.
  */
 function testGetAdLifetimeZoneImpressionsRemaining()
 {
     $aConf =& $GLOBALS['_MAX']['CONF'];
     $aConf['maintenance']['operationInterval'] = 60;
     $aDeliveryLimitations = array();
     $oDeliveryLimitationManager = new OA_Maintenance_Priority_DeliveryLimitation($aDeliveryLimitations);
     // Test 1
     $oDate = new Date('2006-02-15 11:07:15');
     $aCumulativeZoneForecast = array();
     $aCumulativeZoneForecast = $this->_fillForecastArray($aCumulativeZoneForecast);
     $result = $oDeliveryLimitationManager->getAdLifetimeZoneImpressionsRemaining('foo', $oDate, $aCumulativeZoneForecast);
     $this->assertEqual($result, 0);
     $result = $oDeliveryLimitationManager->getAdLifetimeZoneImpressionsRemaining($oDate, 'foo', $aCumulativeZoneForecast);
     $this->assertEqual($result, 0);
     $result = $oDeliveryLimitationManager->getAdLifetimeZoneImpressionsRemaining($oDate, $oDate, 'foo');
     $this->assertEqual($result, 0);
     // Test 2
     $oDate = new Date('2006-02-15 23:07:15');
     $aCumulativeZoneForecast = array();
     $aCumulativeZoneForecast = $this->_fillForecastArray($aCumulativeZoneForecast);
     $result = $oDeliveryLimitationManager->getAdLifetimeZoneImpressionsRemaining($oDate, $oDate, $aCumulativeZoneForecast);
     $this->assertEqual($result, 1);
     $aDates = OX_OperationInterval::convertDateToOperationIntervalStartAndEndDates($oDate);
     $operationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID($aDates['start']);
     $aCumulativeZoneForecast[$operationIntervalID] = 50;
     $previousOperationIntervalId = OX_OperationInterval::previousOperationIntervalID($operationIntervalID);
     $aCumulativeZoneForecast[$previousOperationIntervalId] = 5;
     $nextOperationIntervalId = OX_OperationInterval::nextOperationIntervalID($operationIntervalID);
     $aCumulativeZoneForecast[$nextOperationIntervalId] = 7;
     $aCumulativeZoneForecast = $this->_fillForecastArray($aCumulativeZoneForecast);
     $result = $oDeliveryLimitationManager->getAdLifetimeZoneImpressionsRemaining($oDate, $oDate, $aCumulativeZoneForecast);
     $this->assertEqual($result, 50);
     // Test 3
     $oStartDate = new Date('2006-02-15 11:07:15');
     $oEndDate = new Date('2006-02-15 23:59:59');
     $aCumulativeZoneForecast = array();
     $operationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID(new Date('2006-02-15 10:00:01'));
     $aCumulativeZoneForecast[$operationIntervalID] = 1;
     $operationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID(new Date('2006-02-15 11:00:01'));
     $aCumulativeZoneForecast[$operationIntervalID] = 10;
     $operationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID(new Date('2006-02-15 12:00:01'));
     $aCumulativeZoneForecast[$operationIntervalID] = 100;
     $operationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID(new Date('2006-02-15 13:00:01'));
     $aCumulativeZoneForecast[$operationIntervalID] = 1000;
     $operationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID(new Date('2006-02-15 14:00:01'));
     $aCumulativeZoneForecast[$operationIntervalID] = 10000;
     $operationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID(new Date('2006-02-15 15:00:01'));
     $aCumulativeZoneForecast[$operationIntervalID] = 100000;
     $operationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID(new Date('2006-02-15 16:00:01'));
     $aCumulativeZoneForecast[$operationIntervalID] = 1000000;
     $aCumulativeZoneForecast = $this->_fillForecastArray($aCumulativeZoneForecast);
     $result = $oDeliveryLimitationManager->getAdLifetimeZoneImpressionsRemaining($oStartDate, $oEndDate, $aCumulativeZoneForecast);
     $this->assertEqual($result, 1111110 + 7);
     // Test 4
     $oStartDate = new Date('2006-02-18 22:07:15');
     $oEndDate = new Date('2006-02-20 23:59:59');
     $aCumulativeZoneForecast = array();
     $operationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID(new Date('2006-02-18 21:00:01'));
     $aCumulativeZoneForecast[$operationIntervalID] = 1;
     $operationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID(new Date('2006-02-18 22:00:01'));
     $aCumulativeZoneForecast[$operationIntervalID] = 10;
     $operationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID(new Date('2006-02-18 23:00:01'));
     $aCumulativeZoneForecast[$operationIntervalID] = 100;
     $operationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID(new Date('2006-02-19 00:00:01'));
     $aCumulativeZoneForecast[$operationIntervalID] = 1000;
     $operationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID(new Date('2006-02-19 01:00:01'));
     $aCumulativeZoneForecast[$operationIntervalID] = 10000;
     $operationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID(new Date('2006-02-19 02:00:01'));
     $aCumulativeZoneForecast[$operationIntervalID] = 100000;
     $operationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID(new Date('2006-02-19 03:00:01'));
     $aCumulativeZoneForecast[$operationIntervalID] = 1000000;
     $operationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID(new Date('2006-02-19 04:00:01'));
     $aCumulativeZoneForecast[$operationIntervalID] = 10000000;
     $aCumulativeZoneForecast = $this->_fillForecastArray($aCumulativeZoneForecast);
     $result = $oDeliveryLimitationManager->getAdLifetimeZoneImpressionsRemaining($oStartDate, $oEndDate, $aCumulativeZoneForecast);
     $this->assertEqual($result, 110 + 11111000 + 19 + 24);
     // Test 5
     $oStartDate = new Date('2006-02-07 12:07:15');
     $oEndDate = new Date('2006-02-07 23:59:59');
     $aDeliveryLimitations = array(array('ad_id' => 1, 'logical' => 'and', 'type' => 'deliveryLimitations:Time:Hour', 'comparison' => '!~', 'data' => '23', 'executionorder' => 0));
     $oDeliveryLimitationManager = new OA_Maintenance_Priority_DeliveryLimitation($aDeliveryLimitations);
     $oDeliveryLimitationManager->getActiveAdOperationIntervals(12, $oStartDate, $oEndDate);
     $aCumulativeZoneForecast = array();
     $aCumulativeZoneForecast = $this->_fillForecastArray($aCumulativeZoneForecast);
     $result = $oDeliveryLimitationManager->getAdLifetimeZoneImpressionsRemaining($oStartDate, $oEndDate, $aCumulativeZoneForecast);
     $this->assertEqual($result, 11);
     // Test 6
     $oStartDate = new Date('2006-02-07 12:07:15');
     $oEndDate = new Date('2006-02-08 23:59:59');
     $aDeliveryLimitations = array(array('ad_id' => 1, 'logical' => 'and', 'type' => 'deliveryLimitations:Time:Hour', 'comparison' => '=~', 'data' => '22', 'executionorder' => 0));
     $oDeliveryLimitationManager = new OA_Maintenance_Priority_DeliveryLimitation($aDeliveryLimitations);
     $oDeliveryLimitationManager->getActiveAdOperationIntervals(12, $oStartDate, $oEndDate);
     $aCumulativeZoneForecast = array();
     $aCumulativeZoneForecast = $this->_fillForecastArray($aCumulativeZoneForecast);
     $result = $oDeliveryLimitationManager->getAdLifetimeZoneImpressionsRemaining($oStartDate, $oEndDate, $aCumulativeZoneForecast);
     $this->assertEqual($result, 2);
     TestEnv::restoreConfig();
 }
 /**
  * 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 test the _getAdImpressions() method.
  *
  * Test 1: Test with invalid parameters, and ensure that zero impressions are
  *         allocated.
  * Test 2: Test with an advertisement that is currently blocked, and ensure
  *         that zero impressions are allocated.
  * Test 3: Test with an advertisement that is not currently blocked, but with
  *         no impressions in the cumulative zone forecast, and ensure that
  *         zero impressions are allocated.
  * Test 4: Test with a simple, single operation interval cumulative zone forecast,
  *         and a blocking delivery limitation, and ensure that the correct number
  *         of impressions are allocated.
  * Test 5: Test with a simple, even operation interval cumulative zone forecast,
  *         and a blocking delivery limitation, and ensure that the correct number
  *         of impressions are allocated.
  * Test 6: Test with an uneven operation interval cumulative zone forecast, and
  *         a blocking delivery limitation, and ensure that the correct number of
  *         impressions are allocated.
  */
 function test_getAdImpressions()
 {
     $aConf =& $GLOBALS['_MAX']['CONF'];
     $aConf['maintenance']['operationInterval'] = 60;
     Mock::generatePartial('OA_Maintenance_Priority_Ad', 'PartialMockOA_Maintenance_Priority_Ad', array('getDeliveryLimitations'));
     Mock::generatePartial('OA_Maintenance_Priority_AdServer_Task_GetRequiredAdImpressionsLifetime', 'PartialMockOA_Maintenance_Priority_AdServer_Task_GetRequiredAdImpressionsLifetime', array('_getCumulativeZoneForecast'));
     // Test 1
     $oAd = new OA_Maintenance_Priority_Ad(array('ad_id' => 1, 'weight' => 1, 'status' => OA_ENTITY_STATUS_RUNNING, 'type' => 'sql'));
     $totalRequiredAdImpressions = 10;
     $oDate = new Date();
     $oCampaignExpiryDate = new Date();
     $oGetRequiredAdImpressionsLifetime =& $this->_getCurrentTask();
     $oDeliveryLimitaions = new OA_Maintenance_Priority_DeliveryLimitation(null);
     $aAdZones = array();
     $result = $oGetRequiredAdImpressionsLifetime->_getAdImpressions('foo', $totalRequiredAdImpressions, $oDate, $oCampaignExpiryDate, $oDeliveryLimitaions, $aAdZones);
     $this->assertEqual($result, 0);
     $result = $oGetRequiredAdImpressionsLifetime->_getAdImpressions($oAd, 'foo', $oDate, $oCampaignExpiryDate, $oDeliveryLimitaions, $aAdZones);
     $this->assertEqual($result, 0);
     $result = $oGetRequiredAdImpressionsLifetime->_getAdImpressions($oAd, $totalRequiredAdImpressions, 'foo', $oCampaignExpiryDate, $oDeliveryLimitaions, $aAdZones);
     $this->assertEqual($result, 0);
     $result = $oGetRequiredAdImpressionsLifetime->_getAdImpressions($oAd, $totalRequiredAdImpressions, $oDate, 'foo', $oDeliveryLimitaions, $aAdZones);
     $this->assertEqual($result, 0);
     $result = $oGetRequiredAdImpressionsLifetime->_getAdImpressions($oAd, $totalRequiredAdImpressions, $oDate, $oCampaignExpiryDate, 'foo', $aAdZones);
     $this->assertEqual($result, 0);
     $result = $oGetRequiredAdImpressionsLifetime->_getAdImpressions($oAd, $totalRequiredAdImpressions, $oDate, $oCampaignExpiryDate, $oDeliveryLimitaions, 'foo');
     $this->assertEqual($result, 0);
     // Test 2
     $oAd = new PartialMockOA_Maintenance_Priority_Ad($this);
     $aParam = array('ad_id' => 1, 'weight' => 1, 'status' => OA_ENTITY_STATUS_RUNNING, 'type' => 'sql');
     $oAd->setReturnValue('getDeliveryLimitations', array(array('ad_id' => 1, 'logical' => 'and', 'type' => 'deliveryLimitations:Time:Hour', 'comparison' => '!~', 'data' => '12', 'executionorder' => 0)));
     $oAd->OA_Maintenance_Priority_Ad($aParam);
     $totalRequiredAdImpressions = 120;
     $oDate = new Date('2006-02-15 12:07:01');
     $oCampaignExpiryDate = new Date('2006-12-15 23:59:59');
     $oGetRequiredAdImpressionsLifetime =& $this->_getCurrentTask();
     $oDeliveryLimitaions = new OA_Maintenance_Priority_DeliveryLimitation($oAd->getDeliveryLimitations());
     $aAdZones = array(array('zone_id' => 1));
     $result = $oGetRequiredAdImpressionsLifetime->_getAdImpressions($oAd, $totalRequiredAdImpressions, $oDate, $oCampaignExpiryDate, $oDeliveryLimitaions, $aAdZones);
     $this->assertEqual($result, 0);
     // Test 3
     $oAd = new PartialMockOA_Maintenance_Priority_Ad($this);
     $aParam = array('ad_id' => 1, 'weight' => 1, 'status' => OA_ENTITY_STATUS_RUNNING, 'type' => 'sql');
     $oAd->setReturnValue('getDeliveryLimitations', array(array('ad_id' => 1, 'logical' => 'and', 'type' => 'deliveryLimitations:Time:Hour', 'comparison' => '!~', 'data' => '15', 'executionorder' => 0)));
     $oAd->OA_Maintenance_Priority_Ad($aParam);
     $totalRequiredAdImpressions = 110;
     $oDate = new Date('2006-02-15 12:07:01');
     $oCampaignExpiryDate = new Date('2006-02-15 23:59:59');
     $oGetRequiredAdImpressionsLifetime = new PartialMockOA_Maintenance_Priority_AdServer_Task_GetRequiredAdImpressionsLifetime($this);
     $oGetRequiredAdImpressionsLifetime->setReturnValue('_getCumulativeZoneForecast', array());
     $oGetRequiredAdImpressionsLifetime->OA_Maintenance_Priority_AdServer_Task_GetRequiredAdImpressionsLifetime();
     $oDeliveryLimitaions = new OA_Maintenance_Priority_DeliveryLimitation($oAd->getDeliveryLimitations());
     $aAdZones = array(array('zone_id' => 1));
     $result = $oGetRequiredAdImpressionsLifetime->_getAdImpressions($oAd, $totalRequiredAdImpressions, $oDate, $oCampaignExpiryDate, $oDeliveryLimitaions, $aAdZones);
     $this->assertEqual($result, 0);
     // Test 4
     $oAd = new PartialMockOA_Maintenance_Priority_Ad($this);
     $aParam = array('ad_id' => 1, 'weight' => 1, 'status' => OA_ENTITY_STATUS_RUNNING, 'type' => 'sql');
     $oAd->setReturnValue('getDeliveryLimitations', array(array('ad_id' => 1, 'logical' => 'and', 'type' => 'deliveryLimitations:Time:Hour', 'comparison' => '!~', 'data' => '15', 'executionorder' => 0)));
     $oAd->OA_Maintenance_Priority_Ad($aParam);
     $totalRequiredAdImpressions = 110;
     $oDate = new Date('2006-02-15 12:07:01');
     $oCampaignExpiryDate = new Date('2006-02-15 23:59:59');
     $oGetRequiredAdImpressionsLifetime = new PartialMockOA_Maintenance_Priority_AdServer_Task_GetRequiredAdImpressionsLifetime($this);
     $aCumulativeZoneForecast = array();
     $intervalID = OX_OperationInterval::convertDateToOperationIntervalID(new Date('2006-02-15 12:00:01'));
     $aCumulativeZoneForecast[$intervalID] = 50;
     $aCumulativeZoneForecast = $this->_fillForecastArray($aCumulativeZoneForecast);
     $oGetRequiredAdImpressionsLifetime->setReturnValue('_getCumulativeZoneForecast', $aCumulativeZoneForecast);
     $oGetRequiredAdImpressionsLifetime->OA_Maintenance_Priority_AdServer_Task_GetRequiredAdImpressionsLifetime();
     $oDeliveryLimitaions = new OA_Maintenance_Priority_DeliveryLimitation($oAd->getDeliveryLimitations());
     $remainingOIs = OX_OperationInterval::getIntervalsRemaining($oDate, $oCampaignExpiryDate);
     $oDeliveryLimitaions->getActiveAdOperationIntervals($remainingOIs, $oDate, $oCampaignExpiryDate);
     $aAdZones = array(array('zone_id' => 1));
     $result = $oGetRequiredAdImpressionsLifetime->_getAdImpressions($oAd, $totalRequiredAdImpressions, $oDate, $oCampaignExpiryDate, $oDeliveryLimitaions, $aAdZones);
     $this->assertEqual($result, 110);
     // Test 5
     $oAd = new PartialMockOA_Maintenance_Priority_Ad($this);
     $aParam = array('ad_id' => 1, 'weight' => 1, 'status' => OA_ENTITY_STATUS_RUNNING, 'type' => 'sql');
     $oAd->setReturnValue('getDeliveryLimitations', array(array('ad_id' => 1, 'logical' => 'and', 'type' => 'deliveryLimitations:Time:Hour', 'comparison' => '!~', 'data' => '15', 'executionorder' => 0)));
     $oAd->OA_Maintenance_Priority_Ad($aParam);
     $totalRequiredAdImpressions = 110;
     $oDate = new Date('2006-02-15 12:07:01');
     $oCampaignExpiryDate = new Date('2006-02-15 23:59:59');
     $oGetRequiredAdImpressionsLifetime = new PartialMockOA_Maintenance_Priority_AdServer_Task_GetRequiredAdImpressionsLifetime($this);
     $aCumulativeZoneForecast = array();
     $intervalID = OX_OperationInterval::convertDateToOperationIntervalID(new Date('2006-02-15 12:00:01'));
     $aCumulativeZoneForecast[$intervalID] = 50;
     $intervalID = OX_OperationInterval::convertDateToOperationIntervalID(new Date('2006-02-15 13:00:01'));
     $aCumulativeZoneForecast[$intervalID] = 50;
     $intervalID = OX_OperationInterval::convertDateToOperationIntervalID(new Date('2006-02-15 14:00:01'));
     $aCumulativeZoneForecast[$intervalID] = 50;
     $intervalID = OX_OperationInterval::convertDateToOperationIntervalID(new Date('2006-02-15 15:00:01'));
     $aCumulativeZoneForecast[$intervalID] = 50;
     $intervalID = OX_OperationInterval::convertDateToOperationIntervalID(new Date('2006-02-15 16:00:01'));
     $aCumulativeZoneForecast[$intervalID] = 50;
     $intervalID = OX_OperationInterval::convertDateToOperationIntervalID(new Date('2006-02-15 17:00:01'));
     $aCumulativeZoneForecast[$intervalID] = 50;
     $intervalID = OX_OperationInterval::convertDateToOperationIntervalID(new Date('2006-02-15 18:00:01'));
     $aCumulativeZoneForecast[$intervalID] = 50;
     $intervalID = OX_OperationInterval::convertDateToOperationIntervalID(new Date('2006-02-15 19:00:01'));
     $aCumulativeZoneForecast[$intervalID] = 50;
     $intervalID = OX_OperationInterval::convertDateToOperationIntervalID(new Date('2006-02-15 20:00:01'));
     $aCumulativeZoneForecast[$intervalID] = 50;
     $intervalID = OX_OperationInterval::convertDateToOperationIntervalID(new Date('2006-02-15 21:00:01'));
     $aCumulativeZoneForecast[$intervalID] = 50;
     $intervalID = OX_OperationInterval::convertDateToOperationIntervalID(new Date('2006-02-15 22:00:01'));
     $aCumulativeZoneForecast[$intervalID] = 50;
     $intervalID = OX_OperationInterval::convertDateToOperationIntervalID(new Date('2006-02-15 23:00:01'));
     $aCumulativeZoneForecast[$intervalID] = 50;
     $aCumulativeZoneForecast = $this->_fillForecastArray($aCumulativeZoneForecast);
     $oGetRequiredAdImpressionsLifetime->setReturnValue('_getCumulativeZoneForecast', $aCumulativeZoneForecast);
     $oGetRequiredAdImpressionsLifetime->OA_Maintenance_Priority_AdServer_Task_GetRequiredAdImpressionsLifetime();
     $oDeliveryLimitaions = new OA_Maintenance_Priority_DeliveryLimitation($oAd->getDeliveryLimitations());
     $remainingOIs = OX_OperationInterval::getIntervalsRemaining($oDate, $oCampaignExpiryDate);
     $oDeliveryLimitaions->getActiveAdOperationIntervals($remainingOIs, $oDate, $oCampaignExpiryDate);
     $aAdZones = array(array('zone_id' => 1));
     $result = $oGetRequiredAdImpressionsLifetime->_getAdImpressions($oAd, $totalRequiredAdImpressions, $oDate, $oCampaignExpiryDate, $oDeliveryLimitaions, $aAdZones);
     $this->assertEqual($result, 10);
     // Test 6
     $oAd = new PartialMockOA_Maintenance_Priority_Ad($this);
     $aParam = array('ad_id' => 1, 'weight' => 1, 'status' => OA_ENTITY_STATUS_RUNNING, 'type' => 'sql');
     $oAd->setReturnValue('getDeliveryLimitations', array(array('ad_id' => 1, 'logical' => 'and', 'type' => 'deliveryLimitations:Time:Hour', 'comparison' => '!~', 'data' => '15', 'executionorder' => 0)));
     $oAd->OA_Maintenance_Priority_Ad($aParam);
     $totalRequiredAdImpressions = 110;
     $oDate = new Date('2006-02-15 12:07:01');
     $oCampaignExpiryDate = new Date('2006-02-15 23:59:59');
     $oGetRequiredAdImpressionsLifetime = new PartialMockOA_Maintenance_Priority_AdServer_Task_GetRequiredAdImpressionsLifetime($this);
     $aCumulativeZoneForecast = array();
     $intervalID = OX_OperationInterval::convertDateToOperationIntervalID(new Date('2006-02-15 12:00:01'));
     $aCumulativeZoneForecast[$intervalID] = 10;
     $intervalID = OX_OperationInterval::convertDateToOperationIntervalID(new Date('2006-02-15 13:00:01'));
     $aCumulativeZoneForecast[$intervalID] = 20;
     $intervalID = OX_OperationInterval::convertDateToOperationIntervalID(new Date('2006-02-15 14:00:01'));
     $aCumulativeZoneForecast[$intervalID] = 30;
     $intervalID = OX_OperationInterval::convertDateToOperationIntervalID(new Date('2006-02-15 15:00:01'));
     $aCumulativeZoneForecast[$intervalID] = 40;
     $intervalID = OX_OperationInterval::convertDateToOperationIntervalID(new Date('2006-02-15 16:00:01'));
     $aCumulativeZoneForecast[$intervalID] = 50;
     $intervalID = OX_OperationInterval::convertDateToOperationIntervalID(new Date('2006-02-15 17:00:01'));
     $aCumulativeZoneForecast[$intervalID] = 60;
     $intervalID = OX_OperationInterval::convertDateToOperationIntervalID(new Date('2006-02-15 18:00:01'));
     $aCumulativeZoneForecast[$intervalID] = 50;
     $intervalID = OX_OperationInterval::convertDateToOperationIntervalID(new Date('2006-02-15 19:00:01'));
     $aCumulativeZoneForecast[$intervalID] = 40;
     $intervalID = OX_OperationInterval::convertDateToOperationIntervalID(new Date('2006-02-15 20:00:01'));
     $aCumulativeZoneForecast[$intervalID] = 30;
     $intervalID = OX_OperationInterval::convertDateToOperationIntervalID(new Date('2006-02-15 21:00:01'));
     $aCumulativeZoneForecast[$intervalID] = 20;
     $intervalID = OX_OperationInterval::convertDateToOperationIntervalID(new Date('2006-02-15 22:00:01'));
     $aCumulativeZoneForecast[$intervalID] = 10;
     $intervalID = OX_OperationInterval::convertDateToOperationIntervalID(new Date('2006-02-15 23:00:01'));
     $aCumulativeZoneForecast[$intervalID] = 10;
     $aCumulativeZoneForecast = $this->_fillForecastArray($aCumulativeZoneForecast);
     $oGetRequiredAdImpressionsLifetime->setReturnValue('_getCumulativeZoneForecast', $aCumulativeZoneForecast);
     $oGetRequiredAdImpressionsLifetime->OA_Maintenance_Priority_AdServer_Task_GetRequiredAdImpressionsLifetime();
     $oDeliveryLimitaions = new OA_Maintenance_Priority_DeliveryLimitation($oAd->getDeliveryLimitations());
     $remainingOIs = OX_OperationInterval::getIntervalsRemaining($oDate, $oCampaignExpiryDate);
     $oDeliveryLimitaions->getActiveAdOperationIntervals($remainingOIs, $oDate, $oCampaignExpiryDate);
     $aAdZones = array(array('zone_id' => 1));
     $result = $oGetRequiredAdImpressionsLifetime->_getAdImpressions($oAd, $totalRequiredAdImpressions, $oDate, $oCampaignExpiryDate, $oDeliveryLimitaions, $aAdZones);
     $this->assertEqual($result, 3);
     TestEnv::restoreConfig();
 }
 /**
  * The implementation of the OA_Task::run() method that performs
  * the required task of migrating bucket-based logged data to the
  * statistics table(s) specified by the appropriate plugin
  * components.
  */
 function run()
 {
     $aConf = $GLOBALS['_MAX']['CONF'];
     if ($this->oController->updateIntermediate) {
         // Locate all plugin components which may require bucket data to be
         // migrated from bucket tables to statistics tables
         $aSummariseComponents = $this->_locateComponents();
         // Are there any components that require data to be migrated?
         if (empty($aSummariseComponents)) {
             OA::debug('There are no installed plugins that require data migration', PEAR_LOG_DEBUG);
             return;
         }
         $message = '- Migrating bucket-based logged data to the statistics tables.';
         $this->oController->report .= $message . "\n";
         // Get the MSE DAL to perform the data migration
         $oServiceLocator =& OA_ServiceLocator::instance();
         $oDal =& $oServiceLocator->get('OX_Dal_Maintenance_Statistics');
         // Prepare the "now" date
         $oNowDate =& $oServiceLocator->get('now');
         if (!$oNowDate) {
             $oNowDate = new Date();
         }
         // Prepare an array of possible start and end dates for the migration, unless they have been set already
         if (empty($this->aRunDates)) {
             $this->aRunDates = array();
             $oStartDate = new Date();
             $oStartDate->copy($this->oController->oLastDateIntermediate);
             $oStartDate->addSeconds(1);
             while (Date::compare($oStartDate, $this->oController->oUpdateIntermediateToDate) < 0) {
                 // Calcuate the end of the operation interval
                 $aDates = OX_OperationInterval::convertDateToOperationIntervalStartAndEndDates($oStartDate);
                 $oEndDate = new Date();
                 $oEndDate->copy($aDates['end']);
                 // Store the dates
                 $oStoreStartDate = new Date();
                 $oStoreStartDate->copy($oStartDate);
                 $oStoreEndDate = new Date();
                 $oStoreEndDate->copy($oEndDate);
                 $this->aRunDates[] = array('start' => $oStoreStartDate, 'end' => $oStoreEndDate);
                 // Go to the next operation interval
                 $oStartDate->copy($oEndDate);
                 $oStartDate->addSeconds(1);
             }
         }
         // Check to see if any historical raw data needs to be migrated,
         // post-upgrade, and if so, migrate the data; requires that the
         // default openXDeliveryLog plugin is installed, so the migration
         // will not be called if it is not
         if (key_exists('openXDeliveryLog', $this->aPackages)) {
             $this->_postUpgrade();
         }
         // Prepare arrays of all of the migration maps of raw migrations
         $aRunComponents = $this->_prepareMaps($aSummariseComponents, 'raw');
         // Run each migration map separately, even if it's for the same table
         foreach ($aRunComponents as $statisticsTable => $aMaps) {
             foreach ($aMaps as $componentClassName => $aMigrationDetails) {
                 foreach ($this->aRunDates as $aDates) {
                     $message = "- Migrating raw bucket data from the '{$aMigrationDetails['bucketTable']}' bucket table";
                     OA::debug($message, PEAR_LOG_DEBUG);
                     $message = "  to the '{$statisticsTable}' table, for operation interval range";
                     OA::debug($message, PEAR_LOG_DEBUG);
                     $message = '  ' . $aDates['start']->format('%Y-%m-%d %H:%M:%S') . ' ' . $aDates['start']->tz->getShortName() . ' to ' . $aDates['end']->format('%Y-%m-%d %H:%M:%S') . ' ' . $aDates['end']->tz->getShortName();
                     OA::debug($message, PEAR_LOG_DEBUG);
                     $result = $oDal->summariseBucketsRaw($statisticsTable, $aMigrationDetails, $aDates);
                     if (PEAR::isError($result)) {
                         // Oh noz! The bucket data could not be migrated
                         // Tell the user all about it, but then just keep on truckin'...
                         $message = "   ERROR: Could not migrate raw bucket data from the '{$aMigrationDetails['bucketTable']}' bucket table";
                         OA::debug($message, PEAR_LOG_ERR);
                         $message = "   Error message was: {$result->message}";
                         OA::debug($message, PEAR_LOG_ERR);
                     } else {
                         $message = "  - Migrated {$result} row(s)";
                         OA::debug($message, PEAR_LOG_DEBUG);
                         $pruneResult = $aSummariseComponents[$statisticsTable][$componentClassName]->pruneBucket($aDates['end'], $aDates['start']);
                         if (PEAR::isError($pruneResult)) {
                             // Oh noz! The bucket data could not be pruned, and this is
                             // critical - if we can't prune the data, we'll end up double
                             // counting, so exit with a critical error...
                             $message = "   ERROR: Could not prune aggregate bucket data from the '" . $aSummariseComponents[$statisticsTable][$componentClassName]->getBucketName() . "' bucket table";
                             OA::debug($message, PEAR_LOG_CRIT);
                             $message = "   Error message was: {$pruneResult->message}";
                             OA::debug($message, PEAR_LOG_CRIT);
                             $message = "   Aborting maintenance execution";
                             OA::debug($message, PEAR_LOG_CRIT);
                             exit;
                         } else {
                             $message = "  - Pruned {$pruneResult} row(s)";
                             OA::debug($message, PEAR_LOG_DEBUG);
                         }
                     }
                 }
             }
         }
         // Prepare arrays of all of the migration maps of supplementary raw migrations
         $aRunComponents = $this->_prepareMaps($aSummariseComponents, 'rawSupplementary');
         // Run each migration map separately, even if it's for the same table
         foreach ($aRunComponents as $statisticsTable => $aMaps) {
             foreach ($aMaps as $componentClassName => $aMigrationDetails) {
                 foreach ($this->aRunDates as $aDates) {
                     $message = "- Migrating supplementary raw bucket data from the '{$aMigrationDetails['bucketTable']}' bucket table";
                     OA::debug($message, PEAR_LOG_DEBUG);
                     $message = "  to the '{$statisticsTable}' table, for operation interval range";
                     OA::debug($message, PEAR_LOG_DEBUG);
                     $message = '  ' . $aDates['start']->format('%Y-%m-%d %H:%M:%S') . ' ' . $aDates['start']->tz->getShortName() . ' to ' . $aDates['end']->format('%Y-%m-%d %H:%M:%S') . ' ' . $aDates['end']->tz->getShortName();
                     OA::debug($message, PEAR_LOG_DEBUG);
                     $result = $oDal->summariseBucketsRawSupplementary($statisticsTable, $aMigrationDetails, $aDates);
                     if (PEAR::isError($result)) {
                         // Oh noz! The bucket data could not be migrated
                         // Tell the user all about it, but then just keep on truckin'...
                         $message = "   ERROR: Could not migrate supplementary raw bucket data from the '{$aMigrationDetails['bucketTable']}' bucket table";
                         OA::debug($message, PEAR_LOG_ERR);
                         $message = "   Error message was: {$result->message}";
                         OA::debug($message, PEAR_LOG_ERR);
                     } else {
                         $message = "  - Migrated {$result} row(s)";
                         OA::debug($message, PEAR_LOG_DEBUG);
                         $pruneResult = $aSummariseComponents[$statisticsTable][$componentClassName]->pruneBucket($aDates['end'], $aDates['start']);
                         if (PEAR::isError($pruneResult)) {
                             // Oh noz! The bucket data could not be pruned, and this is
                             // critical - if we can't prune the data, we'll end up double
                             // counting, so exit with a critical error...
                             $message = "   ERROR: Could not prune aggregate bucket data from the '" . $aSummariseComponents[$statisticsTable][$componentClassName]->getBucketName() . "' bucket table";
                             OA::debug($message, PEAR_LOG_CRIT);
                             $message = "   Error message was: {$pruneResult->message}";
                             OA::debug($message, PEAR_LOG_CRIT);
                             $message = "   Aborting maintenance execution";
                             OA::debug($message, PEAR_LOG_CRIT);
                             exit;
                         } else {
                             $message = "  - Pruned {$pruneResult} row(s)";
                             OA::debug($message, PEAR_LOG_DEBUG);
                         }
                     }
                 }
             }
         }
         // Prepare arrays of all of the migration maps of aggregate migrations
         $aRunComponents = $this->_prepareMaps($aSummariseComponents, 'aggregate');
         // Run each migration map by statistics table
         foreach ($aRunComponents as $statisticsTable => $aMaps) {
             $aBucketTables = array();
             foreach ($aMaps as $aMap) {
                 $aBucketTables[] = $aMap['bucketTable'];
             }
             foreach ($this->aRunDates as $aDates) {
                 $aExtras = array();
                 // Is this the data_intermeidate_ad statistics table? It's special!
                 if ($statisticsTable == $aConf['table']['prefix'] . 'data_intermediate_ad') {
                     $aExtras = array('operation_interval' => $aConf['maintenance']['operationInterval'], 'operation_interval_id' => OX_OperationInterval::convertDateToOperationIntervalID($aDates['start']), 'interval_start' => $oDal->oDbh->quote($aDates['start']->format('%Y-%m-%d %H:%M:%S'), 'timestamp') . $oDal->timestampCastString, 'interval_end' => $oDal->oDbh->quote($aDates['end']->format('%Y-%m-%d %H:%M:%S'), 'timestamp') . $oDal->timestampCastString, 'creative_id' => 0, 'updated' => $oDal->oDbh->quote($oNowDate->format('%Y-%m-%d %H:%M:%S'), 'timestamp') . $oDal->timestampCastString);
                 }
                 $message = "- Migrating aggregate bucket data from the '" . implode("', '", $aBucketTables) . "' bucket table(s)";
                 OA::debug($message, PEAR_LOG_DEBUG);
                 $message = "  to the '{$statisticsTable}' table, for operation interval range";
                 OA::debug($message, PEAR_LOG_DEBUG);
                 $message = '  ' . $aDates['start']->format('%Y-%m-%d %H:%M:%S') . ' ' . $aDates['start']->tz->getShortName() . ' to ' . $aDates['end']->format('%Y-%m-%d %H:%M:%S') . ' ' . $aDates['end']->tz->getShortName();
                 OA::debug($message, PEAR_LOG_DEBUG);
                 $result = $oDal->summariseBucketsAggregate($statisticsTable, $aMaps, $aDates, $aExtras);
                 if (PEAR::isError($result)) {
                     // Oh noz! The bucket data could not be migrated
                     // Tell the user all about it, but then just keep on truckin'...
                     $message = "   ERROR: Could not migrate aggregate bucket data from the '" . implode("', '", $aBucketTables) . "' bucket table(s)";
                     OA::debug($message, PEAR_LOG_ERR);
                     $message = "   Error message was: {$result->message}";
                     OA::debug($message, PEAR_LOG_ERR);
                 } else {
                     $message = "  - Migrated {$result} row(s)";
                     OA::debug($message, PEAR_LOG_DEBUG);
                     foreach ($aMaps as $componentClassName => $aMap) {
                         $pruneResult = $aSummariseComponents[$statisticsTable][$componentClassName]->pruneBucket($aDates['end'], $aDates['start']);
                         if (PEAR::isError($pruneResult)) {
                             // Oh noz! The bucket data could not be pruned, and this is
                             // critical - if we can't prune the data, we'll end up double
                             // counting, so exit with a critical error...
                             $message = "   ERROR: Could not prune aggregate bucket data from the '" . $aSummariseComponents[$statisticsTable][$componentClassName]->getBucketName() . "' bucket table";
                             OA::debug($message, PEAR_LOG_CRIT);
                             $message = "   Error message was: {$pruneResult->message}";
                             OA::debug($message, PEAR_LOG_CRIT);
                             $message = "   Aborting maintenance execution";
                             OA::debug($message, PEAR_LOG_CRIT);
                             exit;
                         } else {
                             $message = "  - Pruned {$pruneResult} row(s)";
                             OA::debug($message, PEAR_LOG_DEBUG);
                         }
                     }
                 }
             }
         }
         // Prepare arrays of all of the migration maps of custom migrations
         // (If we refactor stats this will be the one and only method.)
         $aRunComponents = $this->_prepareMaps($aSummariseComponents, 'custom');
         // Run each migration map by statistics table
         foreach ($aRunComponents as $statisticsTable => $aMaps) {
             $aBucketTables = array();
             foreach ($aMaps as $aMap) {
                 $aBucketTables[] = $aMap['bucketTable'];
             }
             foreach ($this->aRunDates as $aDates) {
                 $aExtras = array();
                 $message = "- Migrating aggregate bucket data from the '" . implode("', '", $aBucketTables) . "' bucket table(s)";
                 OA::debug($message, PEAR_LOG_DEBUG);
                 $message = "  to the '{$statisticsTable}' table, for operation interval range";
                 OA::debug($message, PEAR_LOG_DEBUG);
                 $message = '  ' . $aDates['start']->format('%Y-%m%d %H:%M:%S') . ' ' . $aDates['start']->tz->getShortName() . ' to ' . $aDates['end']->format('%Y-%m%d %H:%M:%S') . ' ' . $aDates['end']->tz->getShortName();
                 OA::debug($message, PEAR_LOG_DEBUG);
                 // Call the components migrateStats method.
                 foreach ($aMaps as $componentClassName => $aMap) {
                     $result = $aSummariseComponents[$statisticsTable][$componentClassName]->migrateStatistics($aDates['end']);
                     if (PEAR::isError($result)) {
                         // Oh noz! The bucket data could not be migrated
                         // Tell the user all about it, but then just keep on truckin'...
                         $message = "   ERROR: Could not migrate aggregate bucket data from the '" . implode("', '", $aBucketTables) . "' bucket table(s)";
                         OA::debug($message, PEAR_LOG_ERR);
                         $message = "   Error message was: {$result->message}.";
                         OA::debug($message, PEAR_LOG_ERR);
                     } else {
                         // Only prune the bucket if we migrated the stats successfully.
                         $aSummariseComponents[$statisticsTable][$componentClassName]->pruneBucket($aDates['end'], $aDates['start']);
                     }
                 }
             }
         }
     }
     $this->aRunDates = array();
 }
Beispiel #16
0
 /**
  * A method to convert a Date into an array containing the start
  * and end Dates of the operation interval that the date is in.
  *
  * @static
  * @param Date $oDate The date to convert.
  * @param integer $operation_interval Optional length of the operation interval
  *                                    in minutes. If not given, will use the
  *                                    currently defined operation interval.
  * @param boolean $cacheResult  If true the data should be cached
  * @return array An array of the start and end Dates of the operation interval.
  */
 function convertDateToOperationIntervalStartAndEndDates($oDate, $operationInterval = 0, $cacheResult = true)
 {
     // Convert to UTC
     $oDateCopy = new Date($oDate);
     $oDateCopy->toUTC();
     // Check cache
     static $aCache;
     if ($cacheResult && isset($aCache[$oDateCopy->getDate()][$operationInterval])) {
         $cachedDates = $aCache[$oDateCopy->getDate()][$operationInterval];
         $oStart = new Date($cachedDates['start']);
         $oStart->setTZbyID('UTC');
         $oEnd = new Date($cachedDates['end']);
         $oEnd->setTZbyID('UTC');
         return array('start' => $oStart, 'end' => $oEnd);
     }
     if ($operationInterval < 1) {
         $operationInterval = OX_OperationInterval::getOperationInterval();
     }
     // Get the date representing the start of the week
     $oStartOfWeek = new Date(Date_Calc::beginOfWeek($oDateCopy->getDay(), $oDateCopy->getMonth(), $oDateCopy->getYear(), '%Y-%m-%d 00:00:00'));
     $oStartOfWeek->setTZbyID('UTC');
     // Get the operation interval ID of the date
     $operationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID($oDateCopy, $operationInterval);
     // The start of the operation interval is the start of the week plus the
     // operation interval ID multiplied by the operation interval
     $oStart = new Date();
     $oStart->copy($oStartOfWeek);
     $oStart->addSeconds($operationIntervalID * $operationInterval * 60);
     // The end of the operation interval is the start of the week plus the
     // operation interval ID + 1 multiplied by the operation interval
     $oEnd = new Date();
     $oEnd->copy($oStart);
     $oEnd->addSeconds($operationInterval * 60 - 1);
     // Cache result - cache as string to save memory
     if ($cacheResult) {
         $aCache[$oDate->getDate()][$operationInterval] = array('start' => $oStart->getDate(), 'end' => $oEnd->getDate());
     }
     // Return the result
     return array('start' => $oStart, 'end' => $oEnd);
 }
Beispiel #17
0
 /**
  * A method to get current zone impression forecast(s) for every zone in the
  * system. Where no impression forecast exists for a zone, the default zone
  * impression forecast value (adjusted for the operation interval length) is
  * used. Similarly, if the zone forecast is less that the minimum default
  * zone impression forecast value, then the minimum defauly forecast value
  * is used.
  *
  * Requires that a current day/time (as a Date object) be registered
  * with the OA_ServiceLocator (as "now").
  *
  * @return mixed An array, indexed by zone ID, of the current impression
  *               forecasts, or false if the current datetime not registered
  *               with the OA_ServiceLocator.
  */
 function getZoneImpressionForecasts()
 {
     $aConf = $GLOBALS['_MAX']['CONF'];
     $oServiceLocator =& OA_ServiceLocator::instance();
     $oDate =& $oServiceLocator->get('now');
     if (!$oDate) {
         return false;
     }
     // Prepare the result array
     $aResult = array();
     // Prepare the default zone impression forecast value
     require_once MAX_PATH . '/lib/OA/Maintenance/Priority/AdServer/Task/ForecastZoneImpressions.php';
     $multiplier = $aConf['maintenance']['operationInterval'] / 60;
     $ZONE_FORECAST_DEFAULT_ZONE_IMPRESSIONS = (int) round(ZONE_FORECAST_DEFAULT_ZONE_IMPRESSIONS * $multiplier);
     if ($ZONE_FORECAST_DEFAULT_ZONE_IMPRESSIONS < ZONE_FORECAST_DEFAULT_ZONE_IMPRESSIONS_MINIMUM) {
         $ZONE_FORECAST_DEFAULT_ZONE_IMPRESSIONS = ZONE_FORECAST_DEFAULT_ZONE_IMPRESSIONS_MINIMUM;
     }
     // Get the zone impression forecasts for the current operation interval, where they exist
     $currentOpIntID = OX_OperationInterval::convertDateToOperationIntervalID($oDate);
     $aCurrentDates = OX_OperationInterval::convertDateToOperationIntervalStartAndEndDates($oDate);
     $doData_summary_zone_impression_history = OA_Dal::factoryDO('data_summary_zone_impression_history');
     $doData_summary_zone_impression_history->operation_interval = $aConf['maintenance']['operationInterval'];
     $doData_summary_zone_impression_history->operation_interval_id = $currentOpIntID;
     $doData_summary_zone_impression_history->interval_start = $aCurrentDates['start']->format('%Y-%m-%d %H:%M:%S');
     $doData_summary_zone_impression_history->interval_end = $aCurrentDates['end']->format('%Y-%m-%d %H:%M:%S');
     $doData_summary_zone_impression_history->find();
     while ($doData_summary_zone_impression_history->fetch()) {
         $aResult[$doData_summary_zone_impression_history->zone_id] = $doData_summary_zone_impression_history->forecast_impressions;
     }
     // Get all possible zones in the system
     $doZones = OA_Dal::factoryDO('zones');
     $doZones->find();
     while ($doZones->fetch()) {
         if (!isset($aResult[$doZones->zoneid])) {
             // There is no forecast for this zone, set the forecast to the default value
             $aResult[$doZones->zoneid] = $ZONE_FORECAST_DEFAULT_ZONE_IMPRESSIONS;
         } else {
             if ($aResult[$doZones->zoneid] < ZONE_FORECAST_DEFAULT_ZONE_IMPRESSIONS_MINIMUM) {
                 // The forecast for this zone is less than the permitted minimum, set it
                 // to the minimum permitted value
                 $aResult[$doZones->zoneid] = ZONE_FORECAST_DEFAULT_ZONE_IMPRESSIONS_MINIMUM;
             }
         }
     }
     // Return the result
     return $aResult;
 }
 $aConVariables = Admin_DA::fromCache('getConnectionVariables', $conversionId);
 // Sum up basket values
 $basketValue = 0;
 $numItems = 0;
 foreach ($aConVariables as $conVariable) {
     if ($conVariable['purpose'] == 'basket_value') {
         $basketValue += $conVariable['value'];
     } elseif ($conVariable['purpose'] == 'num_items') {
         $numItems += $conVariable['value'];
     }
 }
 // Get day, $hour and operation interval
 $dateTime = $aConversions[$conversionId]['date_time'];
 $oConnectionDate = new Date($dateTime);
 $oConnectionDate->toUTC();
 $optIntID = OX_OperationInterval::convertDateToOperationIntervalID($oConnectionDate);
 $opDay = $oConnectionDate->format('%Y-%m-%d');
 $opHour = $oConnectionDate->format('%H');
 // Get ad_id, creative_id and zone_id
 $ad_id = $aConversions[$conversionId]['ad_id'];
 $creative_id = $aConversions[$conversionId]['creative_id'];
 $zone_id = $aConversions[$conversionId]['zone_id'];
 $operation = null;
 // If conversion was changed to connection
 if ($aConversions[$conversionId]['connection_status'] == MAX_CONNECTION_STATUS_APPROVED) {
     // Substract conversion from "data_intermediate_ad" and from "data_summary_ad_hourly"
     // and remove $connectionBasketValue from total_basket_value
     $operation = '-';
 }
 // If connection was changed to conversion
 if ($statusId == MAX_CONNECTION_STATUS_APPROVED) {
 /**
  * A method to test the summariseBucketsAggregate() method.
  */
 function testSummariseBucketsAggregate()
 {
     $aConf =& $GLOBALS['_MAX']['CONF'];
     $aConf['maintenance']['operationInterval'] = 60;
     // Prepare standard test parameters
     $statisticsTableName = $aConf['table']['prefix'] . 'data_intermediate_ad';
     $aMigrationMaps = array(0 => array('method' => 'aggregate', 'bucketTable' => $aConf['table']['prefix'] . 'data_bkt_r', 'dateTimeColumn' => 'interval_start', 'groupSource' => array(0 => 'interval_start', 1 => 'creative_id', 2 => 'zone_id'), 'groupDestination' => array(0 => 'date_time', 1 => 'ad_id', 2 => 'zone_id'), 'sumSource' => array(0 => 'count'), 'sumDestination' => array(0 => 'requests'), 'sumDefault' => array(0 => 0)), 1 => array('method' => 'aggregate', 'bucketTable' => $aConf['table']['prefix'] . 'data_bkt_m', 'dateTimeColumn' => 'interval_start', 'groupSource' => array(0 => 'interval_start', 1 => 'creative_id', 2 => 'zone_id'), 'groupDestination' => array(0 => 'date_time', 1 => 'ad_id', 2 => 'zone_id'), 'sumSource' => array(0 => 'count'), 'sumDestination' => array(0 => 'impressions'), 'sumDefault' => array(0 => 0)), 2 => array('method' => 'aggregate', 'bucketTable' => $aConf['table']['prefix'] . 'data_bkt_c', 'dateTimeColumn' => 'interval_start', 'groupSource' => array(0 => 'interval_start', 1 => 'creative_id', 2 => 'zone_id'), 'groupDestination' => array(0 => 'date_time', 1 => 'ad_id', 2 => 'zone_id'), 'sumSource' => array(0 => 'count'), 'sumDestination' => array(0 => 'clicks'), 'sumDefault' => array(0 => 0)));
     $aDates = array('start' => new Date('2008-08-21 09:00:00'), 'end' => new Date('2008-08-21 09:59:59'));
     // Prepare the DAL object
     $oFactory = new OX_Dal_Maintenance_Statistics_Factory();
     $oDalMaintenanceStatistics = $oFactory->factory();
     $oNowDate = new Date();
     $aExtras = array('operation_interval' => $aConf['maintenance']['operationInterval'], 'operation_interval_id' => OX_OperationInterval::convertDateToOperationIntervalID($aDates['start']), 'interval_start' => $oDalMaintenanceStatistics->oDbh->quote($aDates['start']->format('%Y-%m-%d %H:%M:%S'), 'timestamp') . $oDalMaintenanceStatistics->timestampCastString, 'interval_end' => $oDalMaintenanceStatistics->oDbh->quote($aDates['end']->format('%Y-%m-%d %H:%M:%S'), 'timestamp') . $oDalMaintenanceStatistics->timestampCastString, 'creative_id' => 0, 'updated' => $oDalMaintenanceStatistics->oDbh->quote($oNowDate->format('%Y-%m-%d %H:%M:%S'), 'timestamp') . $oDalMaintenanceStatistics->timestampCastString);
     // Test 1: Test with an incorrect method name in the mapping array
     $savedValue = $aMigrationMaps[0]['method'];
     $aMigrationMaps[0]['method'] = 'foo';
     $result = $oDalMaintenanceStatistics->summariseBucketsAggregate($statisticsTableName, $aMigrationMaps, $aDates, $aExtras);
     $this->assertTrue(is_a($result, 'PEAR_Error'));
     $this->assertEqual($result->code, MAX_ERROR_INVALIDARGS);
     $this->assertEqual($result->message, "OX_Dal_Maintenance_Statistics::summariseBucketsAggregate() called with migration map index '0' having method 'foo' != 'aggregate'.");
     $aMigrationMaps[0]['method'] = $savedValue;
     // Test 2: Test with a different number of groupSource and groupDestination columns
     $savedValue = $aMigrationMaps[0]['groupSource'][1];
     unset($aMigrationMaps[0]['groupSource'][1]);
     $result = $oDalMaintenanceStatistics->summariseBucketsAggregate($statisticsTableName, $aMigrationMaps, $aDates, $aExtras);
     $this->assertTrue(is_a($result, 'PEAR_Error'));
     $this->assertEqual($result->code, MAX_ERROR_INVALIDARGS);
     $this->assertEqual($result->message, "OX_Dal_Maintenance_Statistics::summariseBucketsAggregate() called with migration map index '0' having different number of 'groupSource' and 'groupDestination' columns.");
     $aMigrationMaps[0]['groupSource'][1] = $savedValue;
     // Test 3: Test with a different number of sumSource and sumDestination columns
     $savedValue = $aMigrationMaps[1]['sumSource'][0];
     unset($aMigrationMaps[1]['sumSource'][0]);
     $result = $oDalMaintenanceStatistics->summariseBucketsAggregate($statisticsTableName, $aMigrationMaps, $aDates, $aExtras);
     $this->assertTrue(is_a($result, 'PEAR_Error'));
     $this->assertEqual($result->code, MAX_ERROR_INVALIDARGS);
     $this->assertEqual($result->message, "OX_Dal_Maintenance_Statistics::summariseBucketsAggregate() called with migration map index '1' having different number of 'sumSource' and 'sumDestination' columns.");
     $aMigrationMaps[1]['sumSource'][0] = $savedValue;
     // Test 4: Test with a different number of sumSource and sumDefault columns
     $savedValue = $aMigrationMaps[2]['sumDefault'][0];
     unset($aMigrationMaps[2]['sumDefault'][0]);
     $result = $oDalMaintenanceStatistics->summariseBucketsAggregate($statisticsTableName, $aMigrationMaps, $aDates, $aExtras);
     $this->assertTrue(is_a($result, 'PEAR_Error'));
     $this->assertEqual($result->code, MAX_ERROR_INVALIDARGS);
     $this->assertEqual($result->message, "OX_Dal_Maintenance_Statistics::summariseBucketsAggregate() called with migration map index '2' having different number of 'sumSource' and 'sumDefault' columns.");
     $aMigrationMaps[2]['sumDefault'][0] = $savedValue;
     // Test 5: Test with a different groupDestination sets
     $savedValue = $aMigrationMaps[2]['groupDestination'][0];
     $aMigrationMaps[2]['groupDestination'][0] = 'foo';
     $result = $oDalMaintenanceStatistics->summariseBucketsAggregate($statisticsTableName, $aMigrationMaps, $aDates, $aExtras);
     $this->assertTrue(is_a($result, 'PEAR_Error'));
     $this->assertEqual($result->code, MAX_ERROR_INVALIDARGS);
     $this->assertEqual($result->message, "OX_Dal_Maintenance_Statistics::summariseBucketsAggregate() called with migration map indexes '0' and '2' having different 'groupDestination' arrays.");
     $aMigrationMaps[2]['groupDestination'][0] = $savedValue;
     // Test 6: Test with date parameters that are not really dates
     $savedValue = $aDates['start'];
     $aDates['start'] = 'foo';
     $result = $oDalMaintenanceStatistics->summariseBucketsAggregate($statisticsTableName, $aMigrationMaps, $aDates, $aExtras);
     $this->assertTrue(is_a($result, 'PEAR_Error'));
     $this->assertEqual($result->code, MAX_ERROR_INVALIDARGS);
     $this->assertEqual($result->message, "OX_Dal_Maintenance_Statistics::summariseBucketsAggregate() called with invalid start/end date parameters -- not Date objects.");
     $aDates['start'] = $savedValue;
     $savedValue = $aDates['end'];
     $aDates['end'] = 'foo';
     $result = $oDalMaintenanceStatistics->summariseBucketsAggregate($statisticsTableName, $aMigrationMaps, $aDates, $aExtras);
     $this->assertTrue(is_a($result, 'PEAR_Error'));
     $this->assertEqual($result->code, MAX_ERROR_INVALIDARGS);
     $this->assertEqual($result->message, "OX_Dal_Maintenance_Statistics::summariseBucketsAggregate() called with invalid start/end date parameters -- not Date objects.");
     $aDates['end'] = $savedValue;
     // Test 7: Test with invalid start/end dates
     $savedValue = $aDates['start'];
     $aDates['start'] = new Date('2008-08-21 08:00:00');
     $result = $oDalMaintenanceStatistics->summariseBucketsAggregate($statisticsTableName, $aMigrationMaps, $aDates, $aExtras);
     $this->assertTrue(is_a($result, 'PEAR_Error'));
     $this->assertEqual($result->code, MAX_ERROR_INVALIDARGS);
     $this->assertEqual($result->message, "OX_Dal_Maintenance_Statistics::summariseBucketsAggregate() called with invalid start/end date parameters -- not operation interval bounds.");
     $aDates['start'] = $savedValue;
     $savedValue = $aDates['end'];
     $aDates['end'] = new Date('2008-08-22 09:59:59');
     $result = $oDalMaintenanceStatistics->summariseBucketsAggregate($statisticsTableName, $aMigrationMaps, $aDates, $aExtras);
     $this->assertTrue(is_a($result, 'PEAR_Error'));
     $this->assertEqual($result->code, MAX_ERROR_INVALIDARGS);
     $this->assertEqual($result->message, "OX_Dal_Maintenance_Statistics::summariseBucketsAggregate() called with invalid start/end date parameters -- not operation interval bounds.");
     $aDates['end'] = $savedValue;
     // Test 8: Test with an invalid statistics table name
     $savedValue = $statisticsTableName;
     $statisticsTableName = 'foo';
     $result = $oDalMaintenanceStatistics->summariseBucketsAggregate($statisticsTableName, $aMigrationMaps, $aDates, $aExtras);
     $this->assertTrue(is_a($result, 'PEAR_Error'));
     $this->assertEqual($result->code, MAX_ERROR_INVALIDREQUEST);
     $this->assertEqual($result->message, "OX_Dal_Maintenance_Statistics::summariseBucketsAggregate() called with invalid statistics table 'foo'.");
     $statisticsTableName = $savedValue;
     // Test 9: Test with no data_bkt_r table in the database
     $result = $oDalMaintenanceStatistics->summariseBucketsAggregate($statisticsTableName, $aMigrationMaps, $aDates, $aExtras);
     $this->assertTrue(is_a($result, 'PEAR_Error'));
     $this->assertEqual($result->code, MAX_ERROR_INVALIDREQUEST);
     $this->assertEqual($result->message, "OX_Dal_Maintenance_Statistics::summariseBucketsAggregate() called with migration map index '0' having invalid bucket table '{$aConf['table']['prefix']}data_bkt_r'.");
     // Install the openXDeliveryLog plugin, which will create the
     // data_bkt_r, data_bkt_m and data_bkt_c tables required for testing
     TestEnv::installPluginPackage('openXDeliveryLog', false);
     // Test 10: Test with all tables present, but no data
     $result = $oDalMaintenanceStatistics->summariseBucketsAggregate($statisticsTableName, $aMigrationMaps, $aDates, $aExtras);
     $this->assertEqual($result, 0);
     // Insert some data into the data_bkt_r, data_bkt_m and
     // data_bkt_c tables in the incorrect operation interval
     $oData_bkt_r = OA_Dal::factoryDO('data_bkt_r');
     $oData_bkt_r->interval_start = '2008-08-21 08:00:00';
     $oData_bkt_r->creative_id = 1;
     $oData_bkt_r->zone_id = 2;
     $oData_bkt_r->count = 10;
     DataGenerator::generateOne($oData_bkt_r);
     $oData_bkt_m = OA_Dal::factoryDO('data_bkt_m');
     $oData_bkt_m->interval_start = '2008-08-21 08:00:00';
     $oData_bkt_m->creative_id = 1;
     $oData_bkt_m->zone_id = 2;
     $oData_bkt_m->count = 9;
     DataGenerator::generateOne($oData_bkt_m);
     $oData_bkt_c = OA_Dal::factoryDO('data_bkt_c');
     $oData_bkt_c->interval_start = '2008-08-21 08:00:00';
     $oData_bkt_c->creative_id = 1;
     $oData_bkt_c->zone_id = 2;
     $oData_bkt_c->count = 1;
     DataGenerator::generateOne($oData_bkt_c);
     // Test 11: Test with data in the incorrect operation interval
     $result = $oDalMaintenanceStatistics->summariseBucketsAggregate($statisticsTableName, $aMigrationMaps, $aDates, $aExtras);
     $this->assertEqual($result, 0);
     // Insert some data into the data_bkt_r, data_bkt_m and
     // data_bkt_c tables in the incorrect operation interval
     $oData_bkt_r = OA_Dal::factoryDO('data_bkt_r');
     $oData_bkt_r->interval_start = '2008-08-21 09:00:00';
     $oData_bkt_r->creative_id = 1;
     $oData_bkt_r->zone_id = 2;
     $oData_bkt_r->count = 10;
     DataGenerator::generateOne($oData_bkt_r);
     $oData_bkt_m = OA_Dal::factoryDO('data_bkt_m');
     $oData_bkt_m->interval_start = '2008-08-21 09:00:00';
     $oData_bkt_m->creative_id = 1;
     $oData_bkt_m->zone_id = 2;
     $oData_bkt_m->count = 9;
     DataGenerator::generateOne($oData_bkt_m);
     $oData_bkt_c = OA_Dal::factoryDO('data_bkt_c');
     $oData_bkt_c->interval_start = '2008-08-21 09:00:00';
     $oData_bkt_c->creative_id = 1;
     $oData_bkt_c->zone_id = 2;
     $oData_bkt_c->count = 1;
     DataGenerator::generateOne($oData_bkt_c);
     // Test 12: Test with data in the correct operation interval
     $result = $oDalMaintenanceStatistics->summariseBucketsAggregate($statisticsTableName, $aMigrationMaps, $aDates, $aExtras);
     $this->assertEqual($result, 1);
     $oData_intermediate_ad = OA_Dal::factoryDO('data_intermediate_ad');
     $oData_intermediate_ad->find();
     $rows = $oData_intermediate_ad->getRowCount();
     $this->assertEqual($rows, 1);
     $oData_intermediate_ad = OA_Dal::factoryDO('data_intermediate_ad');
     $oData_intermediate_ad->ad_id = 1;
     $oData_intermediate_ad->find();
     $rows = $oData_intermediate_ad->getRowCount();
     $this->assertEqual($rows, 1);
     $oData_intermediate_ad->fetch();
     $this->assertEqual($oData_intermediate_ad->date_time, '2008-08-21 09:00:00');
     $this->assertEqual($oData_intermediate_ad->operation_interval, $aConf['maintenance']['operationInterval']);
     $this->assertEqual($oData_intermediate_ad->operation_interval_id, OX_OperationInterval::convertDateToOperationIntervalID($aDates['start']));
     $this->assertEqual($oData_intermediate_ad->interval_start, '2008-08-21 09:00:00');
     $this->assertEqual($oData_intermediate_ad->interval_end, '2008-08-21 09:59:59');
     $this->assertEqual($oData_intermediate_ad->ad_id, 1);
     $this->assertEqual($oData_intermediate_ad->creative_id, 0);
     $this->assertEqual($oData_intermediate_ad->zone_id, 2);
     $this->assertEqual($oData_intermediate_ad->requests, 10);
     $this->assertEqual($oData_intermediate_ad->impressions, 9);
     $this->assertEqual($oData_intermediate_ad->clicks, 1);
     // Clean up generated data
     DataGenerator::cleanUp();
     // Insert some new data into the data_bkt_r, data_bkt_m and
     // data_bkt_c tables in the incorrect operation interval
     $oData_bkt_r = OA_Dal::factoryDO('data_bkt_r');
     $oData_bkt_r->interval_start = '2008-08-21 09:00:00';
     $oData_bkt_r->creative_id = 2;
     $oData_bkt_r->zone_id = 2;
     $oData_bkt_r->count = 10;
     DataGenerator::generateOne($oData_bkt_r);
     $oData_bkt_m = OA_Dal::factoryDO('data_bkt_m');
     $oData_bkt_m->interval_start = '2008-08-21 09:00:00';
     $oData_bkt_m->creative_id = 2;
     $oData_bkt_m->zone_id = 2;
     $oData_bkt_m->count = 9;
     DataGenerator::generateOne($oData_bkt_m);
     $oData_bkt_c = OA_Dal::factoryDO('data_bkt_c');
     $oData_bkt_c->interval_start = '2008-08-21 09:00:00';
     $oData_bkt_c->creative_id = 2;
     $oData_bkt_c->zone_id = 2;
     $oData_bkt_c->count = 1;
     DataGenerator::generateOne($oData_bkt_c);
     $oData_bkt_r = OA_Dal::factoryDO('data_bkt_r');
     $oData_bkt_r->interval_start = '2008-08-21 09:00:00';
     $oData_bkt_r->creative_id = 11;
     $oData_bkt_r->zone_id = 12;
     $oData_bkt_r->count = 10000;
     DataGenerator::generateOne($oData_bkt_r);
     $oData_bkt_m = OA_Dal::factoryDO('data_bkt_m');
     $oData_bkt_m->interval_start = '2008-08-21 09:00:00';
     $oData_bkt_m->creative_id = 11;
     $oData_bkt_m->zone_id = 12;
     $oData_bkt_m->count = 9960;
     DataGenerator::generateOne($oData_bkt_m);
     $oData_bkt_c = OA_Dal::factoryDO('data_bkt_c');
     $oData_bkt_c->interval_start = '2008-08-21 09:00:00';
     $oData_bkt_c->creative_id = 11;
     $oData_bkt_c->zone_id = 12;
     $oData_bkt_c->count = 500;
     DataGenerator::generateOne($oData_bkt_c);
     // Test 13: Test with new data in the correct operation interval
     $result = $oDalMaintenanceStatistics->summariseBucketsAggregate($statisticsTableName, $aMigrationMaps, $aDates, $aExtras);
     $this->assertEqual($result, 2);
     $oData_intermediate_ad = OA_Dal::factoryDO('data_intermediate_ad');
     $oData_intermediate_ad->find();
     $rows = $oData_intermediate_ad->getRowCount();
     $this->assertEqual($rows, 3);
     $oData_intermediate_ad = OA_Dal::factoryDO('data_intermediate_ad');
     $oData_intermediate_ad->ad_id = 1;
     $oData_intermediate_ad->find();
     $rows = $oData_intermediate_ad->getRowCount();
     $this->assertEqual($rows, 1);
     $oData_intermediate_ad->fetch();
     $this->assertEqual($oData_intermediate_ad->date_time, '2008-08-21 09:00:00');
     $this->assertEqual($oData_intermediate_ad->operation_interval, $aConf['maintenance']['operationInterval']);
     $this->assertEqual($oData_intermediate_ad->operation_interval_id, OX_OperationInterval::convertDateToOperationIntervalID($aDates['start']));
     $this->assertEqual($oData_intermediate_ad->interval_start, '2008-08-21 09:00:00');
     $this->assertEqual($oData_intermediate_ad->interval_end, '2008-08-21 09:59:59');
     $this->assertEqual($oData_intermediate_ad->ad_id, 1);
     $this->assertEqual($oData_intermediate_ad->creative_id, 0);
     $this->assertEqual($oData_intermediate_ad->zone_id, 2);
     $this->assertEqual($oData_intermediate_ad->requests, 10);
     $this->assertEqual($oData_intermediate_ad->impressions, 9);
     $this->assertEqual($oData_intermediate_ad->clicks, 1);
     $oData_intermediate_ad = OA_Dal::factoryDO('data_intermediate_ad');
     $oData_intermediate_ad->ad_id = 2;
     $oData_intermediate_ad->find();
     $rows = $oData_intermediate_ad->getRowCount();
     $this->assertEqual($rows, 1);
     $oData_intermediate_ad->fetch();
     $this->assertEqual($oData_intermediate_ad->date_time, '2008-08-21 09:00:00');
     $this->assertEqual($oData_intermediate_ad->operation_interval, $aConf['maintenance']['operationInterval']);
     $this->assertEqual($oData_intermediate_ad->operation_interval_id, OX_OperationInterval::convertDateToOperationIntervalID($aDates['start']));
     $this->assertEqual($oData_intermediate_ad->interval_start, '2008-08-21 09:00:00');
     $this->assertEqual($oData_intermediate_ad->interval_end, '2008-08-21 09:59:59');
     $this->assertEqual($oData_intermediate_ad->ad_id, 2);
     $this->assertEqual($oData_intermediate_ad->creative_id, 0);
     $this->assertEqual($oData_intermediate_ad->zone_id, 2);
     $this->assertEqual($oData_intermediate_ad->requests, 10);
     $this->assertEqual($oData_intermediate_ad->impressions, 9);
     $this->assertEqual($oData_intermediate_ad->clicks, 1);
     $oData_intermediate_ad = OA_Dal::factoryDO('data_intermediate_ad');
     $oData_intermediate_ad->ad_id = 11;
     $oData_intermediate_ad->find();
     $rows = $oData_intermediate_ad->getRowCount();
     $this->assertEqual($rows, 1);
     $oData_intermediate_ad->fetch();
     $this->assertEqual($oData_intermediate_ad->date_time, '2008-08-21 09:00:00');
     $this->assertEqual($oData_intermediate_ad->operation_interval, $aConf['maintenance']['operationInterval']);
     $this->assertEqual($oData_intermediate_ad->operation_interval_id, OX_OperationInterval::convertDateToOperationIntervalID($aDates['start']));
     $this->assertEqual($oData_intermediate_ad->interval_start, '2008-08-21 09:00:00');
     $this->assertEqual($oData_intermediate_ad->interval_end, '2008-08-21 09:59:59');
     $this->assertEqual($oData_intermediate_ad->ad_id, 11);
     $this->assertEqual($oData_intermediate_ad->creative_id, 0);
     $this->assertEqual($oData_intermediate_ad->zone_id, 12);
     $this->assertEqual($oData_intermediate_ad->requests, 10000);
     $this->assertEqual($oData_intermediate_ad->impressions, 9960);
     $this->assertEqual($oData_intermediate_ad->clicks, 500);
     // Clean up generated data
     DataGenerator::cleanUp();
     // Also clean up the data migrated into the statistics table
     $oData_intermediate_ad = OA_Dal::factoryDO('data_intermediate_ad');
     $oData_intermediate_ad->data_intermediate_ad_id = 1;
     $oData_intermediate_ad->find();
     $oData_intermediate_ad->delete();
     $oData_intermediate_ad = OA_Dal::factoryDO('data_intermediate_ad');
     $oData_intermediate_ad->data_intermediate_ad_id = 2;
     $oData_intermediate_ad->find();
     $oData_intermediate_ad->delete();
     $oData_intermediate_ad = OA_Dal::factoryDO('data_intermediate_ad');
     $oData_intermediate_ad->data_intermediate_ad_id = 3;
     $oData_intermediate_ad->find();
     $oData_intermediate_ad->delete();
     // Uninstall the installed plugin
     TestEnv::uninstallPluginPackage('openXDeliveryLog', false);
     // Restore the test environment configuration
     TestEnv::restoreConfig();
 }
Beispiel #20
0
 /**
  * A method to manage the migration of conversions from the final conversion
  * tables to the old-style intermediate table.
  *
  * @TODO Deprecate, when conversion data is no longer required in the
  *       old format intermediate and summary tables.
  *
  * @param PEAR::Date $oStart The start date/time to migrate from.
  * @param PEAR::Date $oEnd   The end date/time to migrate to.
  */
 function manageConversions($oStart, $oEnd)
 {
     $aConf = $GLOBALS['_MAX']['CONF'];
     // The custom IF function in PgSQL is not suitable for this query, we need explicit use of CASE
     if ($this->oDbh->dbsyntax == 'pgsql') {
         $sqlBasketValue = "CASE WHEN v.purpose = 'basket_value' AND diac.connection_status = " . MAX_CONNECTION_STATUS_APPROVED . " THEN diavv.value::numeric ELSE 0 END";
         $sqlNumItems = "CASE WHEN v.purpose = 'num_items' AND diac.connection_status = " . MAX_CONNECTION_STATUS_APPROVED . " THEN diavv.value::integer ELSE 0 END";
     } else {
         $sqlBasketValue = "IF(v.purpose = 'basket_value' AND diac.connection_status = " . MAX_CONNECTION_STATUS_APPROVED . ", diavv.value, 0)";
         $sqlNumItems = "IF(v.purpose = 'num_items' AND diac.connection_status = " . MAX_CONNECTION_STATUS_APPROVED . ", diavv.value, 0)";
     }
     // Prepare the query to obtain all of the conversions, and their associated total number
     // of items and total basket values (where they exist), ready for update/insertion into
     // the data_intermediate_ad table
     $query = "\n            SELECT\n                DATE_FORMAT(diac.tracker_date_time, '%Y-%m-%d %H:00:00'){$this->timestampCastString} AS date_f,\n                diac.ad_id AS ad_id,\n                diac.zone_id AS zone_id,\n                COUNT(DISTINCT(diac.data_intermediate_ad_connection_id)) AS conversions,\n                SUM({$sqlBasketValue}) AS total_basket_value,\n                SUM({$sqlNumItems}) AS total_num_items\n            FROM\n                " . $this->oDbh->quoteIdentifier($aConf['table']['prefix'] . 'data_intermediate_ad_connection', true) . " AS diac\n            LEFT JOIN\n                " . $this->oDbh->quoteIdentifier($aConf['table']['prefix'] . 'data_intermediate_ad_variable_value', true) . " AS diavv\n            USING\n                (\n                    data_intermediate_ad_connection_id\n                )\n            LEFT JOIN\n                " . $this->oDbh->quoteIdentifier($aConf['table']['prefix'] . 'variables', true) . " AS v\n            ON\n                (\n                    diavv.tracker_variable_id = v.variableid\n                    AND v.purpose IN ('basket_value', 'num_items')\n                )\n            WHERE\n                diac.connection_status = " . MAX_CONNECTION_STATUS_APPROVED . "\n                AND diac.inside_window = 1\n                AND diac.tracker_date_time >= " . $this->oDbh->quote($oStart->format('%Y-%m-%d %H:%M:%S'), 'timestamp') . "\n                AND diac.tracker_date_time <= " . $this->oDbh->quote($oEnd->format('%Y-%m-%d %H:%M:%S'), 'timestamp') . "\n            GROUP BY\n                diac.data_intermediate_ad_connection_id,\n                date_f,\n                diac.ad_id,\n                diac.zone_id";
     OA::debug('- Selecting conversion data for migration to the "old style" intermediate table for ', PEAR_LOG_DEBUG);
     OA::debug('  conversion in the range ' . $oStart->format('%Y-%m-%d %H:%M:%S') . ' ' . $oStart->tz->getShortName() . ' to ' . $oEnd->format('%Y-%m-%d %H:%M:%S') . ' ' . $oEnd->tz->getShortName(), PEAR_LOG_DEBUG);
     $rsResult = $this->oDbh->query($query);
     if (PEAR::isError($rsResult)) {
         return MAX::raiseError($rsResult, MAX_ERROR_DBFAILURE, PEAR_ERROR_DIE);
     }
     while ($aRow = $rsResult->fetchRow()) {
         // Prepare the update query
         $query = "\n                UPDATE\n                    " . $this->oDbh->quoteIdentifier($aConf['table']['prefix'] . 'data_intermediate_ad', true) . "\n                SET\n                    conversions = conversions + " . $this->oDbh->quote($aRow['conversions'], 'integer') . ",\n                    total_basket_value = total_basket_value + " . $this->oDbh->quote($aRow['total_basket_value'], 'float') . ",\n                    total_num_items = total_num_items + " . $this->oDbh->quote($aRow['total_num_items'], 'integer') . "\n                WHERE\n                    date_time = " . $this->oDbh->quote($aRow['date_f'], 'timestamp') . "\n                    AND ad_id = " . $this->oDbh->quote($aRow['ad_id'], 'integer') . "\n                    AND zone_id = " . $this->oDbh->quote($aRow['zone_id'], 'integer');
         $rsUpdateResult = $this->oDbh->exec($query);
         if (PEAR::isError($rsUpdateResult)) {
             return MAX::raiseError($rsUpdateResult, MAX_ERROR_DBFAILURE, PEAR_ERROR_DIE);
         }
         if ($rsUpdateResult == 0) {
             // Could not perform the update - try an insert instead
             $oDate = new Date($aRow['date_f']);
             $operationIntervalId = OX_OperationInterval::convertDateToOperationIntervalID($oDate);
             $aDates = OX_OperationInterval::convertDateToOperationIntervalStartAndEndDates($oDate);
             $query = "\n                    INSERT INTO\n                        " . $this->oDbh->quoteIdentifier($aConf['table']['prefix'] . 'data_intermediate_ad', true) . "\n                        (\n                            date_time,\n                            operation_interval,\n                            operation_interval_id,\n                            interval_start,\n                            interval_end,\n                            ad_id,\n                            creative_id,\n                            zone_id,\n                            conversions,\n                            total_basket_value,\n                            total_num_items\n                        )\n                    VALUES\n                        (\n                            " . $this->oDbh->quote($aRow['date_f'], 'timestamp') . ",\n                            " . $this->oDbh->quote($aConf['maintenance']['operationInterval'], 'integer') . ",\n                            " . $this->oDbh->quote($operationIntervalId, 'integer') . ",\n                            " . $this->oDbh->quote($aDates['start']->format('%Y-%m-%d %H:%M:%S'), 'timestamp') . ",\n                            " . $this->oDbh->quote($aDates['end']->format('%Y-%m-%d %H:%M:%S'), 'timestamp') . ",\n                            " . $this->oDbh->quote($aRow['ad_id'], 'integer') . ",\n                            0,\n                            " . $this->oDbh->quote($aRow['zone_id'], 'integer') . ",\n                            " . $this->oDbh->quote($aRow['conversions'], 'integer') . ",\n                            " . $this->oDbh->quote($aRow['total_basket_value'], 'float') . ",\n                            " . $this->oDbh->quote($aRow['total_num_items'], 'integer') . "\n                        )";
             $rsInsertResult = $this->oDbh->exec($query);
         }
     }
 }
 /**
  * The test to ensure that a campaign with banners that have time-based
  * delivery limitations are correctly prioritised by the MPE.
  *
  * Test Basis:
  *
  * - One campaign, running from 2008-02-26 to 2008-02-27 (2 days).
  * - Booked impressions of 48,000 impressions (i.e. 1,000 per hour
  *     required on average).
  * - Two banners in the zone, both with weight one.
  *   - Banner ID 1 has a Time:Date delivery limitation, to only allow
  *       the banner to deliver on 2008-02-26.
  *   - Banner ID 2 has a Time:Date delivery limitation, to only allow
  *       the banner to deliver on 2008-02-27.
  * - The campaign is linked to one constantly delivering zone (at
  *     1,000 impressions per hour).
  *
  * - Run the MPE with an OI of 60 minutes for the two days of the
  *     campaign lifetime, and assume that all required impressions
  *     allocated to the banner(s) are delivered.
  *
  * The expected result of this is that the MPE should allocate 1,000
  * impressions per hour for Banner ID 1 all day on 2008-02-26, and
  * 1,000 impressions per hour for Banner ID 2 all day on 2008-02-37.
  */
 function testCampaign()
 {
     $aConf =& $GLOBALS['_MAX']['CONF'];
     $aConf['maintenance']['operationInteval'] = 60;
     $aConf['priority']['useZonePatterning'] = false;
     OA_setTimeZone('GMT');
     $oServiceLocator =& OA_ServiceLocator::instance();
     $oServiceLocator->register('now', new Date('2008-02-27'));
     // Prepare the test campaign
     $doCampaigns = OA_Dal::factoryDO('campaigns');
     $doCampaigns->views = 48000;
     $doCampaigns->clicks = -1;
     $doCampaigns->conversions = -1;
     $doCampaigns->activate_time = '2008-02-26 00:00:00';
     $doCampaigns->expire_time = '2008-02-27 23:59:59';
     $doCampaigns->priority = 10;
     $doCampaigns->target_impression = 0;
     $doCampaigns->target_click = 0;
     $doCampaigns->target_conversion = 0;
     $campaignId = DataGenerator::generateOne($doCampaigns);
     // Prepare the first banner
     $doBanners = OA_Dal::factoryDO('banners');
     $doBanners->campaignid = $campaignId;
     $doBanners->active = 't';
     $doBanners->weight = 1;
     $bannerId1 = DataGenerator::generateOne($doBanners);
     $doAcls = OA_Dal::factoryDO('acls');
     $doAcls->bannerid = $bannerId1;
     $doAcls->logical = 'and';
     $doAcls->type = 'deliveryLimitations:Time:Date';
     $doAcls->comparison = '==';
     $doAcls->data = '20080226';
     $doAcls->executionorder = 0;
     DataGenerator::generateOne($doAcls);
     // Prepare the second banner
     $doBanners = OA_Dal::factoryDO('banners');
     $doBanners->campaignid = $campaignId;
     $doBanners->active = 't';
     $doBanners->weight = 1;
     $bannerId2 = DataGenerator::generateOne($doBanners);
     $doAcls = OA_Dal::factoryDO('acls');
     $doAcls->bannerid = $bannerId2;
     $doAcls->logical = 'and';
     $doAcls->type = 'deliveryLimitations:Time:Date';
     $doAcls->comparison = '==';
     $doAcls->data = '20080227';
     $doAcls->executionorder = 0;
     DataGenerator::generateOne($doAcls);
     // Prepare the zone
     $doZones = OA_Dal::factoryDO('zones');
     $zoneId = DataGenerator::generateOne($doZones);
     // Link the banners to the zone
     $doAd_zone_assoc = OA_Dal::factoryDO('ad_zone_assoc');
     $doAd_zone_assoc->zone_id = $zoneId;
     $doAd_zone_assoc->ad_id = $bannerId1;
     DataGenerator::generateOne($doAd_zone_assoc);
     $doAd_zone_assoc = OA_Dal::factoryDO('ad_zone_assoc');
     $doAd_zone_assoc->zone_id = $zoneId;
     $doAd_zone_assoc->ad_id = $bannerId2;
     DataGenerator::generateOne($doAd_zone_assoc);
     // Run the code to get the required ad impressions over
     // the 48 hour period of the test
     for ($counter = 1; $counter <= 48; $counter++) {
         // Set the "current" date/time that the MPE would be
         // running at for the appropriate hour of the test
         $oNowDate = new Date('2008-02-26 00:00:01');
         $oNowDate->addSeconds(($counter - 1) * SECONDS_PER_HOUR);
         $oServiceLocator->register('now', $oNowDate);
         // Run the code to get the required ad impressions
         $oGetRequiredAdImpressionsLifetime = new OA_Maintenance_Priority_AdServer_Task_GetRequiredAdImpressionsLifetime();
         $oGetRequiredAdImpressionsLifetime->run();
         // Test that 1,000 impressions have been "required" for
         // the appropriate banner
         $query = "SELECT * FROM tmp_ad_required_impression";
         $rsRequiredImpression = DBC::NewRecordSet($query);
         $rsRequiredImpression->find();
         $aRequiredImpressions = $rsRequiredImpression->getAll();
         $this->assertTrue(is_array($aRequiredImpressions), "No array for required impressions SQL result in test hour {$counter}");
         $this->assertEqual(count($aRequiredImpressions), 1, "More than one row found for required impressions SQL result in test hour {$counter}");
         $this->assertTrue(is_array($aRequiredImpressions[0]), "Badly formatted result row for required impressions SQL result in test hour {$counter}");
         $this->assertEqual(count($aRequiredImpressions[0]), 2, "Badly formatted result row for required impressions SQL result in test hour {$counter}");
         $bannerId = $aRequiredImpressions[0]['ad_id'];
         if ($counter <= 24) {
             $this->assertEqual($bannerId, $bannerId1, "Expected required impressions for banner ID {$bannerId1} in test hour {$counter}");
         } else {
             $this->assertEqual($bannerId, $bannerId2, "Expected required impressions for banner ID {$bannerId2} in test hour {$counter}");
         }
         $impressions = $aRequiredImpressions[0]['required_impressions'];
         $this->assertEqual($impressions, 1000, "Incorrectly requested {$impressions} impressions instead of 1000 in test hour {$counter}");
         // Insert the required impressions for the banner into the
         // data_intermediate_ad table, as if the delivery has occurred,
         // so that the next hour's test is based on delivery having happened
         $aDates = OX_OperationInterval::convertDateToOperationIntervalStartAndEndDates($oNowDate);
         $operationIntervalId = OX_OperationInterval::convertDateToOperationIntervalID($oNowDate);
         $doData_intermediate_ad = OA_Dal::factoryDO('data_intermediate_ad');
         $doData_intermediate_ad->day = $aDates['start']->format('%Y-%m-%d');
         $doData_intermediate_ad->hour = $aDates['start']->format('%H');
         $doData_intermediate_ad->operation_interval = $aConf['maintenance']['operationInteval'];
         $doData_intermediate_ad->operation_interval_id = $operationIntervalId;
         $doData_intermediate_ad->interval_start = $aDates['start']->format('%Y-%m-%d %H:%M:%S');
         $doData_intermediate_ad->interval_end = $aDates['end']->format('%Y-%m-%d %H:%M:%S');
         $doData_intermediate_ad->ad_id = $bannerId;
         $doData_intermediate_ad->zone_id = $zoneId;
         $doData_intermediate_ad->requests = $impressions;
         $doData_intermediate_ad->impressions = $impressions;
         $doData_intermediate_ad->clicks = 0;
         $doData_intermediate_ad->conversions = 0;
         DataGenerator::generateOne($doData_intermediate_ad);
         // Drop the temporary table that is used to store the
         // required impressions, so that it does not interfer
         // with the next test run in the loop
         unset($GLOBALS['_OA']['DB_TABLES']['tmp_ad_required_impression']);
         $oTable =& OA_DB_Table_Priority::singleton();
         foreach ($oTable->aDefinition['tables'] as $tableName => $aTable) {
             $oTable->truncateTable($tableName);
             $oTable->dropTable($tableName);
         }
     }
 }
Beispiel #22
0
 /**
  * A method to return the forecast impressions for a zone, indexed by operation interval,
  * from the current operation interval through the past week. If no forecast stored in
  * the database for a given OI, uses average of forecasts found.
  *
  * @param integer $zoneId The Zone ID.
  * @return mixed An array on success, false on failure. The array is of the format:
  *                   array(
  *                       [operation_interval_id] => array(
  *                                                      ['zone_id']               => zone_id,
  *                                                      ['_impressions']  => forecast_impressions,
  *                                                      ['operation_interval_id'] => operation_interval_id
  *                                                  )
  *                       [operation_interval_id] => array(
  *                                                      ['zone_id']               => zone_id,
  *                                                      ['forecast_impressions']  => forecast_impressions,
  *                                                      ['operation_interval_id'] => operation_interval_id
  *                                                  )
  *                                   .
  *                                   .
  *                                   .
  *                   )
  */
 function getPreviousWeekZoneForcastImpressions($zoneId)
 {
     if (empty($zoneId) || !is_numeric($zoneId)) {
         OA::debug('Invalid zone ID argument', PEAR_LOG_ERR);
         return false;
     }
     $aConf = $GLOBALS['_MAX']['CONF'];
     $oServiceLocator =& OA_ServiceLocator::instance();
     $oDate =& $oServiceLocator->get('now');
     if (!$oDate) {
         return false;
     }
     // Get previous OI
     $oPreviousOI = new Date($oDate);
     $oPreviousOI->subtractSeconds(OX_OperationInterval::getOperationInterval() * 60);
     // Get the start and end ranges of the current week, up to the previous OI
     $aDates = OX_OperationInterval::convertDateToOperationIntervalStartAndEndDates($oPreviousOI);
     $oDateWeekStart = new Date();
     $oDateWeekStart->copy($aDates['end']);
     $oDateWeekStart->subtractSeconds(SECONDS_PER_WEEK - 1);
     $oDateWeekEnd = new Date();
     $oDateWeekEnd->copy($aDates['end']);
     // Select the zone forecasts from the database
     $tableName = $this->_getTablename('data_intermediate_ad');
     $oneHourInterval = OA_Dal::quoteInterval(1, 'hour');
     $query = "\n            SELECT\n                SUM(impressions) AS forecast_impressions,\n                operation_interval_id AS operation_interval_id,\n                interval_start AS interval_start,\n                interval_end AS interval_end\n            FROM\n            {$tableName}\n            WHERE\n                zone_id = {$zoneId}\n                AND operation_interval = {$aConf['maintenance']['operationInterval']}\n                AND interval_start >= '" . $oDateWeekStart->format('%Y-%m-%d %H:%M:%S') . "'\n                AND interval_end <= '" . $oDateWeekEnd->format('%Y-%m-%d %H:%M:%S') . "'\n                AND date_time > DATE_SUB('" . $oDateWeekStart->format('%Y-%m-%d %H:%M:%S') . "', {$oneHourInterval})\n                AND date_time < DATE_ADD('" . $oDateWeekEnd->format('%Y-%m-%d %H:%M:%S') . "', {$oneHourInterval})\n                AND zone_id != 0\n            GROUP BY\n            \tinterval_start,\n            \tinterval_end,\n            \toperation_interval_id\n            ORDER BY\n                interval_start";
     $rc = $this->oDbh->query($query);
     $totalForecastImpressions = 0;
     $count = 0;
     if (!PEAR::isError($rc)) {
         // Sort the results into an array indexed by the operation interval ID
         $aFinalResult = array();
         while ($aRow = $rc->fetchRow()) {
             $aFinalResult[$aRow['operation_interval_id']] = array('zone_id' => $zoneId, 'forecast_impressions' => $aRow['forecast_impressions'], 'operation_interval_id' => $aRow['operation_interval_id']);
             $count++;
             $totalForecastImpressions += $aRow['forecast_impressions'];
         }
     }
     $averageForecastImpressions = 0;
     if ($count > 0) {
         $averageForecastImpressions = floor($totalForecastImpressions / $count);
     }
     if ($averageForecastImpressions == 0) {
         $averageForecastImpressions = $this->getZoneForecastDefaultZoneImpressions();
     }
     // Check each operation interval ID has a forecast impression value,
     // and if not, set to the system default.
     for ($operationIntervalID = 0; $operationIntervalID < OX_OperationInterval::operationIntervalsPerWeek(); $operationIntervalID++) {
         if (!isset($aFinalResult[$operationIntervalID])) {
             $aFinalResult[$operationIntervalID] = array('zone_id' => $zoneId, 'forecast_impressions' => $averageForecastImpressions, 'operation_interval_id' => $operationIntervalID);
         }
     }
     // Overwrite current OI with previous OI to match the zone forecasting algorithm
     $currOI = OX_OperationInterval::convertDateToOperationIntervalID($oDate);
     $prevOI = OX_OperationInterval::previousOperationIntervalID($currOI);
     $aFinalResult[$currOI]['forecast_impressions'] = $aFinalResult[$prevOI]['forecast_impressions'];
     // Return data
     return $aFinalResult;
 }
 /**
  * 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);
 }