示例#1
0
 public function __construct($oStart, $oEnd, $aEntityParams)
 {
     $oNow = new Date();
     $this->oStart = $oNow->before($oStart) ? $oNow : $oStart;
     $this->oEnd = $oNow->before($oEnd) ? $oNow : $oEnd;
     $this->parseEntityParams($aEntityParams);
 }
 /**
  * A method to test the getPlacementFirstStatsDate() method.
  *
  * Requirements:
  * Test 1: Test with an invalid placement ID, and ensure null is returned.
  * Test 2: Test with no data in the database, and ensure current date is returned.
  * Test 3: Test with single row in the database, and ensure correct date is
  *         returned.
  * Test 4: Test with multi rows in the database, and ensure correct date is
  *         returned.
  */
 function testGetPlacementFirstStatsDate()
 {
     $conf =& $GLOBALS['_MAX']['CONF'];
     $oDbh =& OA_DB::singleton();
     $oDalStatistics = new MAX_Dal_Statistics();
     // Test 1
     $placementId = 'foo';
     $oResult = $oDalStatistics->getPlacementFirstStatsDate($placementId);
     $this->assertNull($oResult);
     // Test 2
     $placementId = 1;
     $oBeforeDate = new Date();
     sleep(1);
     $oResult = $oDalStatistics->getPlacementFirstStatsDate($placementId);
     sleep(1);
     $oAfterDate = new Date();
     $this->assertTrue(is_a($oResult, 'Date'));
     $this->assertTrue($oBeforeDate->before($oResult));
     $this->assertTrue($oAfterDate->after($oResult));
     // Test 3
     $oNow = new Date();
     $aData = array('campaignid' => $placementId, 'active' => 't', 'updated' => $oNow->format('%Y-%m-%d %H:%M:%S'), 'acls_updated' => $oNow->format('%Y-%m-%d %H:%M:%S'));
     $idBanner1 = $this->_insertBanner($aData);
     $aData = array('day' => '2006-10-30', 'hour' => 12, 'ad_id' => $idBanner1, 'updated' => $oNow->format('%Y-%m-%d %H:%M:%S'));
     $idDSAH1 = $this->_insertDataSummaryAdHourly($aData);
     $oResult = $oDalStatistics->getPlacementFirstStatsDate($placementId);
     $oExpectedDate = new Date('2006-10-30 12:00:00');
     $this->assertEqual($oResult, $oExpectedDate);
     // Test 4
     $aData = array('campaignid' => $placementId, 'active' => 't', 'updated' => $oNow->format('%Y-%m-%d %H:%M:%S'), 'acls_updated' => $oNow->format('%Y-%m-%d %H:%M:%S'));
     $idBanner2 = $this->_insertBanner($aData);
     $aData = array('campaignid' => 999, 'active' => 't', 'updated' => $oNow->format('%Y-%m-%d %H:%M:%S'), 'acls_updated' => $oNow->format('%Y-%m-%d %H:%M:%S'));
     $idBanner3 = $this->_insertBanner($aData);
     $aData = array('day' => '2006-10-29', 'hour' => 12, 'ad_id' => $idBanner2, 'updated' => $oNow->format('%Y-%m-%d %H:%M:%S'));
     $idDSAH1 = $this->_insertDataSummaryAdHourly($aData);
     $aData = array('day' => '2006-10-28', 'hour' => 12, 'ad_id' => $idBanner2, 'updated' => $oNow->format('%Y-%m-%d %H:%M:%S'));
     $idDSAH2 = $this->_insertDataSummaryAdHourly($aData);
     $aData = array('day' => '2006-10-27', 'hour' => 12, 'ad_id' => $idBanner2, 'updated' => $oNow->format('%Y-%m-%d %H:%M:%S'));
     $idDSAH3 = $this->_insertDataSummaryAdHourly($aData);
     $aData = array('day' => '2006-10-26', 'hour' => 12, 'ad_id' => 999, 'updated' => $oNow->format('%Y-%m-%d %H:%M:%S'));
     $idDSAH4 = $this->_insertDataSummaryAdHourly($aData);
     $oResult = $oDalStatistics->getPlacementFirstStatsDate($placementId);
     $oExpectedDate = new Date('2006-10-27 12:00:00');
     $this->assertEqual($oResult, $oExpectedDate);
     DataGenerator::cleanUp();
 }
示例#3
0
 /**
  * A method to check if the campaign is awaiting activation
  *
  * @return bool
  */
 function _isAwaiting()
 {
     static $oServiceLocator;
     // MySQL null date hardcoded for optimisation
     if (!empty($this->activate) && $this->activate != '0000-00-00') {
         if (!isset($oServiceLocator)) {
             $oServiceLocator =& OA_ServiceLocator::instance();
         }
         if (!($oNow = $oServiceLocator->get('now'))) {
             $oNow = new Date();
         }
         $oActivate = new Date($this->activate);
         if (!empty($this->clientid)) {
             // Set timezone
             $aAccounts = $this->getOwningAccountIds();
             $aPrefs = OA_Preferences::loadAccountPreferences($aAccounts[OA_ACCOUNT_ADVERTISER], true);
             if (isset($aPrefs['timezone'])) {
                 $oActivate->setTZbyID($aPrefs['timezone']);
             }
         }
         if ($oNow->before($oActivate)) {
             return true;
         }
     }
     return false;
 }
示例#4
0
 /**
  * A method to calculate the range of dates that a statistics screen needs to display.
  *
  * Returns an array of values where:
  *
  *  - If "week" or "day" is the breakdown, array is of days, indexed by "YYYY-MM-DD",
  *    and formatted using the user's local format for days.
  *
  *  - If "month" is the breakdown, array is of months, indexed by "YYYY-MM",
  *    and formatted using the user's local format for months and days.
  *
  *  - If "dow" is the breakdown, array is of days of the week, indexed by the integers
  *    0 to 6, and formatted with the user's local weekday names.
  *
  *  - If "hour" is the breakdown, array is of hours of the day, indexed by the integers
  *    0 to 23, and formatted in the format "00:00 - 00:59", "01:00 01:59", etc.
  *
  * @param array      $aDates          An array of the start and end dates in use by the day
  *                                    span selector element, if set.
  * @param string     $breakdown       The breakdown type in use. One of "week", "day", "month",
  *                                    "dow" or "hour".
  * @param PEAR::Date $oStatsStartDate A date object representing the first day of statistics
  *                                    that are available.
  * @return array The array, as described above.
  */
 function getDatesArray($aDates, $breakdown, $oStatsStartDate)
 {
     // Does the day span selector element have dates set?
     if ($aDates['day_begin'] && $aDates['day_end'] || $aDates['period_start'] && $aDates['period_end']) {
         if ($aDates['day_begin'] && $aDates['day_end']) {
             // Use the dates given by the day span selector element
             $oStartDate = new Date($aDates['day_begin']);
             $oEndDate = new Date($aDates['day_end']);
         } else {
             // Use the dates given by the period_start and period_end
             $oStartDate = new Date($aDates['period_start']);
             $oEndDate = new Date($aDates['period_end']);
         }
         // Adjust end date to be now, if it's in the future
         if ($oEndDate->isFuture()) {
             $oEndDate = new Date();
             $aDates['day_end'] = new Date();
             $aDates['day_end'] = $aDates['day_end']->format('%Y-%m-%d');
         }
     } else {
         // Use the dates given by the statistics date limitation
         // and now
         $oStartDate = new Date();
         $oStartDate->copy($oStatsStartDate);
         $oEndDate = new Date();
     }
     // Prepare the return array
     $aDatesResult = array();
     switch ($breakdown) {
         case 'week':
         case 'day':
             $oOneDaySpan = new Date_Span('1', '%d');
             $oEndDate->addSpan($oOneDaySpan);
             $oDate = new Date();
             $oDate->copy($oStartDate);
             while ($oDate->before($oEndDate)) {
                 $aDatesResult[$oDate->format('%Y-%m-%d')] = $oDate->format($GLOBALS['date_format']);
                 $oDate->addSpan($oOneDaySpan);
             }
             break;
         case 'month':
             $oOneMonthSpan = new Date_Span((string) ($oEndDate->getDaysInMonth() - $oEndDate->getDay() + 1), '%d');
             $oEndDate->addSpan($oOneMonthSpan);
             $oDate = new Date();
             $oDate->copy($oStartDate);
             while ($oDate->before($oEndDate)) {
                 $aDatesResult[$oDate->format('%Y-%m')] = $oDate->format($GLOBALS['month_format']);
                 $oOneMonthSpan = new Date_Span((string) ($oDate->getDaysInMonth() - $oDate->getDay() + 1), '%d');
                 $oDate->addSpan($oOneMonthSpan);
             }
             break;
         case 'dow':
             for ($dow = 0; $dow < 7; $dow++) {
                 $aDatesResult[$dow] = $GLOBALS['strDayFullNames'][$dow];
             }
             break;
         case 'hour':
             for ($hour = 0; $hour < 24; $hour++) {
                 $aDatesResult[$hour] = sprintf('%02d:00 - %02d:59', $hour, $hour);
             }
             break;
     }
     return $aDatesResult;
 }
示例#5
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;
 }
示例#6
0
 /**
  * A method to get the most recent details of contract campaign creative delivery
  * for a given list of creative/zone pairs set to deliver in the current
  * operation interval. Normally, the data will be retrieved from the previous
  * operation interval, but if no data exists for that creative/zone pair, then the
  * next previous operation interval will be tried, and so on, up to a limit
  * of MAX_PREVIOUS_AD_DELIVERY_INFO_LIMIT minutes (default is one week).
  *
  * - Requires that a current day/time (as a Date object) be registered
  *   with the OA_ServiceLocator (as "now").
  *
  * - Ignores creative ID 0 and zone ID 0 items, as these are reserved for
  *   direct selection, which is considered to be outside the process of
  *   priority compensation calculations (even though priority values for
  *   all contract campaign creatives are calculated and stored for the
  *   zone ID 0).
  *
  * Note: The logic of this method seems a little convoluted, and it is.
  * However, it needs to be. The reason being:
  *
  *  - If a contract campaign creative delivered in the previous operation interval,
  *    then it should have had a priority set in ad_zone_assoc (that's how OpenX
  *    knows to deliver contract campiang creatives, natch!). This should be the most
  *    recent entry in data_summary_ad_zone_assoc. So, the first step is to get the
  *    data for all contract campiang creatives that have delivered in the previous
  *    OI, and the associated prioritisation data.
  *  - If a contract campaign creative did not deliver, the prioritisation data set
  *    in the previous OI is still needed anyway (as it might have been *supposed*
  *    to deliver), so the second step is to get those creatives that had
  *    prioiritisation data set in the previous OI, but did not deliver.
  *  - Finally, as some creatives are limited by hour (for example), we want to
  *    to be able to get past prioritisation data for creatives that were
  *    disabled in the last OI, so, we need to look for creative/zone pairs
  *    that have not yet been found, and get BOTH the prioritisation AND the
  *    delivery data from the last OI when the creatives were active in the
  *    zones.
  *
  * This is why the method uses a complex, 3 step process!
  *
  * @access public
  * @param array $aCurrentZones An array of Zones, indexed by Zone ID, with each
  *                             Zone containing the Advert objects that are linked
  *                             to deliver in the zone, in the current operation
  *                             interval.
  * @return mixed An array of arrays of arrays, each one representing a set of
  *               ad/zone delivery information, indexed by ad ID and zone ID.
  *               Each sub-sub array, if present, has the format:
  *               array (
  *                  'ad_id'                         => integer
  *                  'zone_id'                       => integer
  *                  'required_impressions'          => integer
  *                  'requested_impressions'         => integer
  *                  'priority_factor'               => double
  *                  'past_zone_traffic_fraction'    => double
  *                  'impressions'                   => integer
  *               )
  *               Returns false when the current date/time is not set in the
  *               OA_ServiceLocator.
  */
 function &getPreviousAdDeliveryInfo($aCurrentZones)
 {
     OA::debug("  - Getting details of previous creative/zone delivery", PEAR_LOG_DEBUG);
     $aConf = $GLOBALS['_MAX']['CONF'];
     $oServiceLocator =& OA_ServiceLocator::instance();
     $oDate =& $oServiceLocator->get('now');
     if (!$oDate) {
         return false;
     }
     $aAds = array();
     $aZones = array();
     $aZonesAds = array();
     $aPastDeliveryResult = array();
     $aPastPriorityResult = array();
     $aNonDeliveringPastPriorityResult = array();
     $aFinalResult = array();
     // Obtain the earliest existing interval_start date found in the
     // data_summary_ad_zone_assoc table
     $table = $this->_getTablename('data_summary_ad_zone_assoc');
     $query = "\n            SELECT\n                interval_start AS interval_start\n            FROM\n            {$table}\n            ORDER BY\n                interval_start\n            LIMIT\n                1";
     $rc = $this->oDbh->query($query);
     if (!PEAR::isError($rc) && $rc->numRows() == 1) {
         $aRow = $rc->fetchRow();
         $oEarliestPastPriorityRecordDate = new Date($aRow['interval_start']);
         // Create a new date that is the limit number of minutes ago
         $oLimitDate = new Date();
         $oLimitDate->copy($oDate);
         $oLimitDate->subtractSeconds(MAX_PREVIOUS_AD_DELIVERY_INFO_LIMIT * 60);
         // Is the earliest date before this date?
         if ($oEarliestPastPriorityRecordDate->before($oLimitDate)) {
             // Use the limit date instead
             $oEarliestPastPriorityRecordDate = new Date();
             $oEarliestPastPriorityRecordDate->copy($oLimitDate);
         }
     }
     // Obtain the operation interval ID, and the start and end dates of the previous
     // operation interval
     $currentOperationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID($oDate);
     $previousOperationIntervalID = OX_OperationInterval::previousOperationIntervalID($currentOperationIntervalID);
     $aDates = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($oDate);
     // Obtain the ad ID, zone ID and number of impressions delivered for every ad/zone
     // combination that delivered impressions in the previous operation interval, where
     // the ad is from a contract campaign (as we don't care about other campaign types)
     OA::debug("  - Getting details of contract campaign creative/zone pairs that delivered last OI", PEAR_LOG_DEBUG);
     $sDataIntermediateAd = $this->_getTablename('data_intermediate_ad');
     $sBanners = $this->_getTablename('banners');
     $sCampaigns = $this->_getTablename('campaigns');
     $query = "\n            SELECT\n                ad_id AS ad_id,\n                zone_id AS zone_id,\n                SUM(impressions) AS impressions\n            FROM\n            {$sDataIntermediateAd} AS dia,\n            {$sBanners} AS b,\n            {$sCampaigns} AS c\n            WHERE\n                dia.operation_interval = {$aConf['maintenance']['operationInterval']}\n                AND\n                dia.operation_interval_id = {$previousOperationIntervalID}\n                AND\n                dia.interval_start = '" . $aDates['start']->format('%Y-%m-%d %H:%M:%S') . "'\n                AND\n                dia.interval_end = '" . $aDates['end']->format('%Y-%m-%d %H:%M:%S') . "'\n                AND\n                dia.ad_id != 0\n                AND\n                dia.zone_id != 0\n                AND\n                dia.ad_id = b.bannerid\n                AND\n                b.campaignid = c.campaignid\n                AND\n                c.priority > 0\n            GROUP BY\n                ad_id,\n                zone_id\n            ORDER BY\n                ad_id,\n                zone_id";
     $rc = $this->oDbh->query($query);
     while ($aRow = $rc->fetchRow()) {
         // Store the ad ID as being one that has delivered
         $aAds[$aRow['ad_id']] = $aRow['ad_id'];
         // Store the zone ID as one that had impressions in it
         $aZones[$aRow['zone_id']] = $aRow['zone_id'];
         // Store the ad IDs by zone ID
         $aZonesAds[$aRow['zone_id']][$aRow['ad_id']] = true;
         // Store the impressions delivered for the contract campaign creative/zone pair,
         // and that the past priority information for this contract campiang creative/zone
         // pair has not been found yet (it will be found later on)
         $aPastDeliveryResult[$aRow['ad_id']][$aRow['zone_id']]['impressions'] = $aRow['impressions'];
         $aPastDeliveryResult[$aRow['ad_id']][$aRow['zone_id']]['pastPriorityFound'] = false;
     }
     // Did any ads deliver last operation interval?
     if (!empty($aAds)) {
         // Is there past deliver data?
         if (isset($oEarliestPastPriorityRecordDate)) {
             // As all of the above contract capiang creative/zone combinations delivered impressions
             // in the previous operation interval, a priority value must have existed. However, the
             // priority value may *not* have come from the previous interval, as maintenance may not
             // have been run (although it should have ;-)
             // To be sure, interate backwards over past operation intervals (up to the earliest
             // existing record), obtaining the details of the impressions requested and the priority
             // values used for the above combinations
             $previousOperationIntervalIDLoop = $previousOperationIntervalID;
             $aDatesLoop = array();
             $aDatesLoop['start'] = new Date();
             $aDatesLoop['start']->copy($aDates['start']);
             $aDatesLoop['end'] = new Date();
             $aDatesLoop['end']->copy($aDates['end']);
             $foundAll = false;
             while (!$foundAll) {
                 if (!empty($aAds) && !empty($aZones)) {
                     OA::debug('    - Getting past details of contract campiang creative/zone pairs for OI starting at ' . $aDatesLoop['start']->format('%Y-%m-%d %H:%M:%S'), PEAR_LOG_DEBUG);
                     $table = $this->_getTablename('data_summary_ad_zone_assoc');
                     $query = "\n                            SELECT\n                                ad_id AS ad_id,\n                                zone_id AS zone_id,\n                                required_impressions AS required_impressions,\n                                requested_impressions AS requested_impressions,\n                                to_be_delivered AS to_be_delivered,\n                                priority_factor AS priority_factor,\n                                past_zone_traffic_fraction AS past_zone_traffic_fraction,\n                                created AS created,\n                                expired AS expired\n                            FROM\n                            {$table}\n                            WHERE\n                                ad_id IN (" . implode(', ', $aAds) . ")\n                                AND\n                                zone_id IN (" . implode(', ', $aZones) . ")\n                                AND\n                                operation_interval = {$aConf['maintenance']['operationInterval']}\n                                AND\n                                operation_interval_id = {$previousOperationIntervalIDLoop}\n                                AND\n                                interval_start = '" . $aDatesLoop['start']->format('%Y-%m-%d %H:%M:%S') . "'\n                                AND\n                                interval_end = '" . $aDatesLoop['end']->format('%Y-%m-%d %H:%M:%S') . "'\n                            ORDER BY\n                                ad_id,\n                                zone_id";
                     $rc = $this->oDbh->query($query);
                     $aResult = $rc->fetchAll();
                     // Calculate the past priority results, using $aPastDeliveryResult in the call to
                     // _calculateAveragePastPriorityValues(), so that if this is the second (or greater)
                     // time this has been done then any contract campiang creative/zone pairs that have
                     // come up with details for a second (or greater) time (i.e. as a result of a priority
                     // value record from an earise operation interval as we iterate backwards in time) will
                     // NOT have its past priority info re-calculated with the wrong values
                     $this->_calculateAveragePastPriorityValues($aPastPriorityResult, $aResult, $oDate, $aPastDeliveryResult);
                     // Loop over the results, marking off the contract campiang banner/zone
                     // combinations in the past delivery array as having had their past prioritisation
                     // information found and/or calculated
                     if (!empty($aPastPriorityResult)) {
                         foreach ($aPastPriorityResult as $a => $aAd) {
                             foreach ($aAd as $z => $aZone) {
                                 if ($aZone['pastPriorityFound']) {
                                     $aPastDeliveryResult[$a][$z]['pastPriorityFound'] = true;
                                 }
                             }
                         }
                     }
                 }
                 // Look over the past delivery array to see if there are any contract campaign creative/zone
                 // combinations that do not yet have the past prioritisation information
                 $foundAll = true;
                 if (!empty($aPastDeliveryResult)) {
                     foreach ($aPastDeliveryResult as $a => $aAd) {
                         $remove = true;
                         foreach ($aAd as $z => $aZone) {
                             if (!$aPastDeliveryResult[$a][$z]['pastPriorityFound']) {
                                 if ($foundAll) {
                                     // Need to go back in time to look for more past priority info
                                     $previousOperationIntervalIDLoop = OX_OperationInterval::previousOperationIntervalID($previousOperationIntervalIDLoop);
                                     $aDatesLoop = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($aDatesLoop['start']);
                                     if (!$aDatesLoop['start']->before($oEarliestPastPriorityRecordDate)) {
                                         // Haven't exceeded earliest priority info date, so okay
                                         // to go ahead with going back in time...
                                         $foundAll = false;
                                     }
                                 }
                                 $remove = false;
                             }
                             // Remove the contract campaign creative from the list of creatives to select
                             // from next round, and check if this was the last creative in the zone, and,
                             // if so, also remove the zone from the list of zones to select from
                             // next round
                             if ($remove) {
                                 unset($aAds[$a]);
                                 unset($aZonesAds[$z][$a]);
                                 if (count($aZonesAds[$z]) == 0) {
                                     unset($aZones[$z]);
                                 }
                             }
                         }
                     }
                 }
             }
         }
         // Merge the past priority and delivery values into the final results array
         if (!empty($aPastDeliveryResult)) {
             foreach ($aPastDeliveryResult as $a => $aAd) {
                 foreach ($aAd as $z => $aZone) {
                     $aFinalResult[$a][$z] = array('ad_id' => $a, 'zone_id' => $z, 'required_impressions' => $aPastPriorityResult[$a][$z]['required_impressions'], 'requested_impressions' => $aPastPriorityResult[$a][$z]['requested_impressions'], 'to_be_delivered' => $aPastPriorityResult[$a][$z]['to_be_delivered'], 'priority_factor' => $aPastPriorityResult[$a][$z]['priority_factor'], 'past_zone_traffic_fraction' => $aPastPriorityResult[$a][$z]['past_zone_traffic_fraction'], 'impressions' => $aPastDeliveryResult[$a][$z]['impressions']);
                 }
             }
         }
     }
     // Select the details of all contract campaign creative/zones that had required/requested impressions,
     // in the previous operation interval, but for which no impressions were delivered
     OA::debug('  - Getting details of contract campaign creative/zone pairs that did not deliver last OI (but should have)', PEAR_LOG_DEBUG);
     $table1 = $this->_getTablename('data_summary_ad_zone_assoc');
     $table2 = $this->_getTablename('data_intermediate_ad');
     $oneHourInterval = OA_Dal::quoteInterval(1, 'hour');
     // we have to do this complicated MINUS query (mysql doesn't support MINUS so we do a LEFT JOIN exclude not matching)
     // and we do two subqueries in order to use the INDEXes as expected
     // note the trick that we use range lookup on the date_time field as this is the one that is indexed
     $query = "\n            SELECT dsaza.*\n            FROM (\n                SELECT\n                    ad_id AS ad_id,\n                    zone_id AS zone_id,\n                    required_impressions AS required_impressions,\n                    requested_impressions AS requested_impressions,\n                    to_be_delivered AS to_be_delivered,\n                    priority_factor AS priority_factor,\n                    past_zone_traffic_fraction AS past_zone_traffic_fraction,\n                    created AS created,\n                    expired AS expired\n                FROM\n                {$table1} AS dsaza\n                WHERE\n                    operation_interval = {$aConf['maintenance']['operationInterval']}\n                    AND\n                    operation_interval_id = {$previousOperationIntervalID}\n                    AND\n                    interval_start = '" . $aDates['start']->format('%Y-%m-%d %H:%M:%S') . "'\n                    AND\n                    interval_end = '" . $aDates['end']->format('%Y-%m-%d %H:%M:%S') . "'\n                    AND\n                    ad_id != 0\n                    AND\n                    zone_id != 0\n                    AND\n                    required_impressions > 0\n                    AND\n                    requested_impressions > 0\n                ORDER BY\n                    ad_id,\n                    zone_id\n            ) as dsaza\n            LEFT JOIN\n            (\n            \tSELECT\n            \t\tad_id,\n            \t\tzone_id\n            \tFROM\n            \t{$table2} AS dia\n                WHERE\n                    operation_interval = {$aConf['maintenance']['operationInterval']}\n                    AND\n                    operation_interval_id = {$previousOperationIntervalID}\n                    AND\n                    interval_start = '" . $aDates['start']->format('%Y-%m-%d %H:%M:%S') . "'\n                    AND\n                    interval_end = '" . $aDates['end']->format('%Y-%m-%d %H:%M:%S') . "'\n                    AND\n                    date_time > DATE_SUB('" . $aDates['start']->format('%Y-%m-%d %H:%M:%S') . "', {$oneHourInterval})\n                    AND\n                    date_time < DATE_ADD('" . $aDates['start']->format('%Y-%m-%d %H:%M:%S') . "', {$oneHourInterval})\n                ORDER BY\n                    ad_id,\n                    zone_id\n            ) as dia\n            ON\n                dsaza.ad_id = dia.ad_id\n                AND\n                dsaza.zone_id = dia.zone_id\n            WHERE\n                dia.ad_id IS NULL\n                AND\n                dia.zone_id IS NULL\n            ";
     $rc = $this->oDbh->query($query);
     $aResult = $rc->fetchAll();
     $resultCount = count($aResult);
     OA::debug('    - Found ' . $resultCount . ' contract campaign creative/zone pairs that did not deliver last OI (but should have)', PEAR_LOG_DEBUG);
     if ($resultCount > 0) {
         // Calculate the past priority results, but without the optional parameter to
         // _calculateAveragePastPriorityValues(), as this is a single calculation on data
         // in the past OI, and no further looping back over time will occur
         OA::debug('  - Getting past details of the non-delivering contract campiang creative/zone pairs', PEAR_LOG_DEBUG);
         $this->_calculateAveragePastPriorityValues($aNonDeliveringPastPriorityResult, $aResult, $oDate);
         // Merge the past priority values into the final results array
         if (!empty($aNonDeliveringPastPriorityResult)) {
             foreach ($aNonDeliveringPastPriorityResult as $a => $aAd) {
                 foreach ($aAd as $z => $aZone) {
                     if (empty($aFinalResult[$a][$z])) {
                         $aFinalResult[$a][$z] = array('ad_id' => $a, 'zone_id' => $z, 'required_impressions' => $aNonDeliveringPastPriorityResult[$a][$z]['required_impressions'], 'requested_impressions' => $aNonDeliveringPastPriorityResult[$a][$z]['requested_impressions'], 'to_be_delivered' => $aNonDeliveringPastPriorityResult[$a][$z]['to_be_delivered'], 'priority_factor' => $aNonDeliveringPastPriorityResult[$a][$z]['priority_factor'], 'past_zone_traffic_fraction' => $aNonDeliveringPastPriorityResult[$a][$z]['past_zone_traffic_fraction']);
                     }
                 }
             }
         }
     }
     // Finally, now that all contract campaign creative/zone combinations that had required/requested
     // impressions in the previous operation interval and delivered/didn't deliver issues have been
     // dealt with, check to see if there are any contract campaign creative/zone combinations that are
     // linked to deliver in the current operation interval, which are not covered by the above
     OA::debug('  - Finding contract campaign creative/zone pairs set to deliver, but with no past data yet', PEAR_LOG_DEBUG);
     $aAds = array();
     $aZones = array();
     $aZonesAds = array();
     $aNotInLastOIPastDeliveryResult = array();
     $aNotInLastOIPastPriorityResult = array();
     if (is_array($aCurrentZones) && !empty($aCurrentZones)) {
         foreach ($aCurrentZones as $zoneId => $oZone) {
             // Ignore Zone ID 0, as data for this zone is not required (there will no be
             // priority compensation performed on this zone, the past data is not relevant)
             if ($oZone->id != 0) {
                 if (is_array($oZone->aAdverts) && !empty($oZone->aAdverts)) {
                     foreach ($oZone->aAdverts as $oAdvert) {
                         // Store that the past priority information for this contract campiagn creative/zone
                         // pair may not have yet been found
                         $aNotInLastOIPastDeliveryResult[$oAdvert->id][$zoneId]['pastPriorityFound'] = false;
                     }
                 }
             }
         }
     }
     // Remove those contract campiagn creative/zone pairs that have,
     // in fact, already had their past priority information found
     if (!empty($aFinalResult)) {
         foreach ($aFinalResult as $aResult) {
             if (isset($aResult['ad_id'])) {
                 unset($aNotInLastOIPastDeliveryResult[$aResult['ad_id']][$aResult['zone_id']]);
             }
         }
         foreach ($aNotInLastOIPastDeliveryResult as $adKey => $aTestZone) {
             if (empty($aTestZone)) {
                 unset($aNotInLastOIPastDeliveryResult[$adKey]);
             }
         }
     }
     // Create the sets of required creatives and zones that need their past priority
     // information from older operation intervals found (exluding zone ID 0, as this
     // is not required)
     if (!empty($aNotInLastOIPastDeliveryResult)) {
         foreach ($aNotInLastOIPastDeliveryResult as $adKey => $aData) {
             // Store the creative ID as being one that needs to deliver
             $aAds[$adKey] = $adKey;
             foreach ($aData as $zoneKey => $value) {
                 // Store the zone ID as one that has a creative that needs to deliver in it
                 $aZones[$zoneKey] = $zoneKey;
                 // Store the creative ID by zone ID
                 $aZonesAds[$zoneKey][$adKey] = true;
             }
         }
     }
     // Are there any contract campiagn creative/zone pairs that need data?
     if (!empty($aNotInLastOIPastDeliveryResult)) {
         // Is there past delivery data?
         if (isset($oEarliestPastPriorityRecordDate)) {
             // Loop over the previous operation intervals, starting with the one
             // *before* last, and find when (if possible) these contract campiagn
             // creative/zone pairs last *requested* to deliver; it doesn't matter if
             // they did deliver in that operation interval or not
             $previousOperationIntervalIDLoop = OX_OperationInterval::previousOperationIntervalID($previousOperationIntervalID);
             $aDatesLoop = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($aDates['start']);
             $foundAll = false;
             while (!$foundAll) {
                 if (!empty($aAds) && !empty($aZones)) {
                     OA::debug('    - Getting past details of contract campiagn creative/zone pairs which did not deliver last OI, for OI ' . 'starting at ' . $aDatesLoop['start']->format('%Y-%m-%d %H:%M:%S'), PEAR_LOG_DEBUG);
                     $table = $this->_getTablename('data_summary_ad_zone_assoc');
                     $query = "\n                            SELECT\n                                ad_id AS ad_id,\n                                zone_id AS zone_id,\n                                required_impressions AS required_impressions,\n                                requested_impressions AS requested_impressions,\n                                to_be_delivered AS to_be_delivered,\n                                priority_factor AS priority_factor,\n                                past_zone_traffic_fraction AS past_zone_traffic_fraction,\n                                created AS created,\n                                expired AS expired,\n                                operation_interval AS operation_interval,\n                                operation_interval_id AS operation_interval_id,\n                                interval_start AS interval_start,\n                                interval_end AS interval_end\n                            FROM\n                            {$table}\n                            WHERE\n                                ad_id IN (" . implode(', ', $aAds) . ")\n                                AND\n                                zone_id IN (" . implode(', ', $aZones) . ")\n                                AND\n                                operation_interval = {$aConf['maintenance']['operationInterval']}\n                                AND\n                                operation_interval_id = {$previousOperationIntervalIDLoop}\n                                AND\n                                interval_start = '" . $aDatesLoop['start']->format('%Y-%m-%d %H:%M:%S') . "'\n                                AND\n                                interval_end = '" . $aDatesLoop['end']->format('%Y-%m-%d %H:%M:%S') . "'\n                            ORDER BY\n                                ad_id,\n                                zone_id";
                     $rc = $this->oDbh->query($query);
                     $aResult = $rc->fetchAll();
                     // Calculate the past priority results, using $aPastDeliveryResult in the call to
                     // _calculateAveragePastPriorityValues(), so that if this is the second (or greater)
                     // time this has been done then any contract campiang creative/zone pairs that have
                     // come up with details for a second (or greater) time (i.e. as a result of a priority
                     // value record from an earise operation interval as we iterate backwards in time) will
                     // NOT have its past priority info re-calculated with the wrong values
                     $this->_calculateAveragePastPriorityValues($aNotInLastOIPastPriorityResult, $aResult, $oDate, $aNotInLastOIPastDeliveryResult);
                     // Loop over the results, marking off the contract campiagn creative/zone
                     // combinations in the past delivery array as having had their past prioritisation
                     // information found and/or calculated
                     if (!empty($aNotInLastOIPastPriorityResult)) {
                         foreach ($aNotInLastOIPastPriorityResult as $a => $aAd) {
                             foreach ($aAd as $z => $aZone) {
                                 if ($aZone['pastPriorityFound']) {
                                     $aNotInLastOIPastDeliveryResult[$a][$z]['pastPriorityFound'] = true;
                                 }
                             }
                         }
                     }
                     // Look over the past delivery array to see if there are any contract campiagn creative/zone
                     // combinations that do not yet have the past prioritisation information
                     $foundAll = true;
                     if (!empty($aNotInLastOIPastDeliveryResult)) {
                         foreach ($aNotInLastOIPastDeliveryResult as $a => $aAd) {
                             $remove = true;
                             foreach ($aAd as $z => $aZone) {
                                 if (!$aNotInLastOIPastDeliveryResult[$a][$z]['pastPriorityFound']) {
                                     if ($foundAll) {
                                         // Need to go back in time to look for more past priority info
                                         $previousOperationIntervalIDLoop = OX_OperationInterval::previousOperationIntervalID($previousOperationIntervalIDLoop);
                                         $aDatesLoop = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($aDatesLoop['start']);
                                         if (!$aDatesLoop['start']->before($oEarliestPastPriorityRecordDate)) {
                                             // Haven't exceeded earliest priority info date, so okay
                                             // to go ahead with going back in time...
                                             $foundAll = false;
                                         }
                                     }
                                     $remove = false;
                                 }
                                 // Remove the creative from the list of creatives to select from next round,
                                 // and check if this was the last creative in the zone, and, if so,
                                 // also remove the zone from the list of zones to select from
                                 // next round
                                 if ($remove) {
                                     unset($aAds[$a]);
                                     unset($aZonesAds[$z][$a]);
                                     if (count($aZonesAds[$z]) == 0) {
                                         unset($aZones[$z]);
                                     }
                                 }
                             }
                         }
                     }
                 } else {
                     $foundAll = true;
                 }
             }
         }
         // Now that it is known when (if) the remaining creatives last requested to deliver,
         // determine how many impressions were delivered (if any) during the appropriate
         // operation intervals
         if (!empty($aNotInLastOIPastPriorityResult)) {
             $table = $this->_getTablename('data_intermediate_ad');
             $oneHourInterval = OA_Dal::quoteInterval(1, 'hour');
             $query = "\n                    SELECT\n                        SUM(impressions) AS impressions\n                    FROM\n                    {$table}\n                    WHERE\n                        operation_interval = ?\n                        AND\n                        operation_interval_id = ?\n                        AND\n                        date_time > DATE_SUB(?, " . $oneHourInterval . ")\n                        AND\n                        date_time < DATE_ADD(?, " . $oneHourInterval . ")\n                        AND\n                        interval_start = ?\n                        AND\n                        interval_end = ?\n                        AND\n                        ad_id = ?\n                        AND\n                        zone_id = ?";
             $aTypes = array('integer', 'integer', 'timestamp', 'timestamp', 'timestamp', 'timestamp', 'integer', 'integer');
             $stSelectSumImpressions = $this->oDbh->prepare($query, $aTypes, MDB2_PREPARE_RESULT);
             OA::debug('  - Looping over each zone linked to ' . count($aNotInLastOIPastPriorityResult) . ' ads');
             $countQueriesSumImp = 0;
             foreach ($aNotInLastOIPastPriorityResult as $a => $aAd) {
                 OA::debug('    - Requesting sum of impressions for ad ID ' . $a . ' for ' . count($aAd) . ' zones ', PEAR_LOG_DEBUG);
                 foreach ($aAd as $z => $aZone) {
                     $aData = array($aNotInLastOIPastPriorityResult[$a][$z]['operation_interval'], $aNotInLastOIPastPriorityResult[$a][$z]['operation_interval_id'], $aNotInLastOIPastPriorityResult[$a][$z]['interval_start'], $aNotInLastOIPastPriorityResult[$a][$z]['interval_start'], $aNotInLastOIPastPriorityResult[$a][$z]['interval_start'], $aNotInLastOIPastPriorityResult[$a][$z]['interval_end'], $a, $z);
                     $rsResult = $stSelectSumImpressions->execute($aData);
                     $aResult = $rsResult->fetchAll();
                     if (isset($aResult[0]['impressions'])) {
                         $aNotInLastOIPastPriorityResult[$a][$z]['impressions'] = $aResult[0]['impressions'];
                     }
                     $countQueriesSumImp++;
                 }
             }
             OA::debug('  - Finished querying impressions for ' . $countQueriesSumImp . ' ad-zones combinations');
         }
         // Merge the past priority and delivery values into the final results array
         if (!empty($aNotInLastOIPastPriorityResult)) {
             foreach ($aNotInLastOIPastPriorityResult as $a => $aAd) {
                 foreach ($aAd as $z => $aZone) {
                     if (empty($aFinalResult[$a][$z])) {
                         $aFinalResult[$a][$z] = array('ad_id' => $a, 'zone_id' => $z, 'required_impressions' => $aNotInLastOIPastPriorityResult[$a][$z]['required_impressions'], 'requested_impressions' => $aNotInLastOIPastPriorityResult[$a][$z]['requested_impressions'], 'to_be_delivered' => $aNotInLastOIPastPriorityResult[$a][$z]['to_be_delivered'], 'priority_factor' => $aNotInLastOIPastPriorityResult[$a][$z]['priority_factor'], 'past_zone_traffic_fraction' => $aNotInLastOIPastPriorityResult[$a][$z]['past_zone_traffic_fraction']);
                         if (isset($aNotInLastOIPastPriorityResult[$a][$z]['impressions'])) {
                             $aFinalResult[$a][$z]['impressions'] = $aNotInLastOIPastPriorityResult[$a][$z]['impressions'];
                         }
                     }
                 }
             }
         }
     }
     return $aFinalResult;
 }
 /**
  * ???
  *
  * @param integer $zoneId The ID of the zone to be tested.
  * @param unknown_type $campaignid ???
  * @param unknown_type $newStart ???
  * @param unknown_type $newEnd ???
  * @return unknown ???
  */
 function _checkEmailZoneAdAssoc($zoneId, $campaignid, $newStart = false, $newEnd = false)
 {
     // Suppress PEAR error handling for this method...
     PEAR::pushErrorHandling(null);
     require_once 'Date.php';
     // This is an email zone, so check all current linked ads for active date ranges
     $aOtherAds = Admin_DA::getAdZones(array('zone_id' => $zoneId));
     $campaignVariables = Admin_DA::getPlacement($campaignid);
     if ($newStart) {
         $campaignVariables['activate_time'] = $newStart;
     }
     if ($newEnd) {
         $campaignVariables['expire_time'] = $newEnd;
     }
     if (empty($campaignVariables['activate_time']) && empty($campaignVariables['expire_time'])) {
         return PEAR::raiseError($GLOBALS['strEmailNoDates'], MAX_ERROR_EMAILNODATES);
     }
     $campaignStart = new Date($campaignVariables['activate_time']);
     $campaignStart->setTZbyID('UTC');
     $campaignEnd = new Date($campaignVariables['expire_time']);
     $campaignEnd->setTZbyID('UTC');
     $okToLink = true;
     foreach ($aOtherAds as $azaID => $aAdVariables) {
         $aOtherAdVariables = Admin_DA::getAd($aAdVariables['ad_id']);
         if ($aOtherAdVariables['placement_id'] == $campaignid) {
             continue;
         }
         $otherCampaignVariables = Admin_DA::getPlacement($aOtherAdVariables['placement_id']);
         if (empty($otherCampaignVariables['activate_time']) || empty($otherCampaignVariables['expire_time'])) {
             $okToLink = false;
             break;
         }
         // Do not allow link if either start or end date is within another linked campaign dates
         $otherCampaignStart = new Date($otherCampaignVariables['activate_time']);
         $otherCampaignStart->setTZbyID('UTC');
         $otherCampaignEnd = new Date($otherCampaignVariables['expire_time']);
         $otherCampaignEnd->setTZbyID('UTC');
         if ($campaignStart->after($otherCampaignStart) && $campaignStart->before($otherCampaignEnd) || $campaignStart->equals($otherCampaignStart)) {
             $okToLink = false;
             break;
         }
         if ($campaignEnd->after($otherCampaignStart) && $campaignEnd->before($otherCampaignEnd) || $campaignEnd->equals($otherCampaignEnd)) {
             $okToLink = false;
             break;
         }
     }
     if (!$okToLink) {
         $link = "campaign-edit.php?clientid={$otherCampaignVariables['advertiser_id']}&campaignid={$otherCampaignVariables['placement_id']}";
         return PEAR::raiseError($GLOBALS['strDatesConflict'] . ": <a href='{$link}'>" . $otherCampaignVariables['name'] . "</a>", MAX_ERROR_EXISTINGCAMPAIGNFORDATES);
     }
     PEAR::popErrorHandling();
     return true;
 }
示例#8
0
文件: example.php 项目: MagnusA/Date
<h4>Display micro-time:</h4>
<?php 
$date->setSecond(3.201282);
echo_code($date->format('%d/%m/%Y %I.%M.%s'));
echo_code($date->format2('DD/MM/YYYY HH12.MI.SS.FFFFFF'));
?>
<h4>Convert to Unix time:</h4>
<?php 
echo_code($hn_unixtime = $date->format2('U'));
?>
<h4>Convert Unix time back to Date object:</h4>
<?php 
$date2 = new Date($hn_unixtime);
echo_code($date2->format2("DD/MM/YYYY HH.MI.SSTZO"));
?>
<h4>Compare two times for equality:</h4>
<?php 
if ($date2->before($date)) {
    echo "second date is earlier (because Unix time ignores the part-second)<br />\n";
}
$date->trunc(DATE_PRECISION_SECOND);
if ($date2->equals($date)) {
    echo "dates are now the same<br />\n";
}
?>
<br />
<br />
<br />
<br />
</body>
</html>
 /**
  * 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;
 }
示例#10
0
    echo "Adding " . $oOIStart->format('%Y-%m-%d %H:%M:%S') . "' -> '" . $oOIEnd->format('%Y-%m-%d %H:%M:%S') . " to the list of run dates<br />\n";
    // Store the dates
    $oStoreStartDate = new Date();
    $oStoreStartDate->copy($oOIStart);
    $oStoreEndDate = new Date();
    $oStoreEndDate->copy($oOIEnd);
    $aRunDates[] = array('start' => $oStoreStartDate, 'end' => $oStoreEndDate);
    $oOIEnd = OX_OperationInterval::addOperationIntervalTimeSpan($oOIEnd);
    $oOIStart = OX_OperationInterval::addOperationIntervalTimeSpan($oOIStart);
}
// The summariseFinal process requires complete hours (not OI's), so record these too
$oOIStart = new Date(INTERVAL_START);
$oOIEnd = new Date(INTERVAL_START);
$oOIEnd->addSeconds(60 * 60 - 1);
$aRunHours = array();
while ($oOIEnd->before($oEndDate) || $oOIEnd->equals($oEndDate)) {
    echo "Adding " . $oOIStart->format('%Y-%m-%d %H:%M:%S') . "' -> '" . $oOIEnd->format('%Y-%m-%d %H:%M:%S') . " to the list of run dates<br />\n";
    // Store the dates
    $oStoreStartDate = new Date();
    $oStoreStartDate->copy($oOIStart);
    $oStoreEndDate = new Date();
    $oStoreEndDate->copy($oOIEnd);
    $aRunHours[] = array('start' => $oStoreStartDate, 'end' => $oStoreEndDate);
    $oOIEnd->addSeconds(60 * 60);
    $oOIStart->addSeconds(60 * 60);
}
// Create and register an instance of the OA_Dal_Maintenance_Statistics DAL class for the following tasks to use
$oServiceLocator =& OA_ServiceLocator::instance();
if (!$oServiceLocator->get('OX_Dal_Maintenance_Statistics')) {
    $oFactory = new OX_Dal_Maintenance_Statistics_Factory();
    $oDal = $oFactory->factory();
 private function updateExpandedDates($start, $end, $updateTransferal = true)
 {
     if ($this->beginDate->equals($this->originalBeginDate)) {
         return;
     }
     $accountManager = new AccountManager($this->badgerDb);
     $compareAccount = $accountManager->getAccountById($this->account->getId());
     $compareAccount->setFilter(array(array('key' => 'plannedTransactionId', 'op' => 'eq', 'val' => $this->id), array('key' => 'valutaDate', 'op' => 'ge', 'val' => new Date($start)), array('key' => 'valutaDate', 'op' => 'le', 'val' => new Date($end))));
     $compareAccount->setOrder(array(array('key' => 'valutaDate', 'dir' => 'asc')));
     $date = new Date($this->beginDate);
     $originalDate = new Date($this->originalBeginDate);
     $windowStart = $this->previousOccurence(new Date($originalDate), $this->originalBeginDate);
     $windowEnd = $this->nextOccurence(new Date($originalDate), $this->originalBeginDate);
     while (!$date->after($windowStart)) {
         $date = $this->nextOccurence($date);
     }
     while ($currentCompareTransaction = $compareAccount->getNextTransaction()) {
         while ($originalDate->before($currentCompareTransaction->getValutaDate())) {
             $originalDate = $this->nextOccurence($originalDate, $this->originalBeginDate);
             $date = $this->nextOccurence($date);
         }
         if ($originalDate->equals($currentCompareTransaction->getValutaDate())) {
             $currentCompareTransaction->setValutaDate(new Date($date));
         }
     }
     //while compareTransactions
     if ($updateTransferal && $this->transferalTransaction) {
         $this->transferalTransaction->updateExpandedDates($start, $end, false);
     }
 }
function transferFormerFinishedTransactions($account)
{
    global $us;
    if ($us->getProperty('autoExpandPlannedTransactions') == false) {
        return;
    }
    $now = new Date();
    $now->setHour(0);
    $now->setMinute(0);
    $now->setSecond(0);
    $account->setType('planned');
    $account->setFilter(array(array('key' => 'beginDate', 'op' => 'le', 'val' => $now)));
    try {
        $lastInsertDate = $us->getProperty('Account_' . $account->getId() . '_LastTransferFormerFinishedTransactions');
    } catch (BadgerException $ex) {
        $lastInsertDate = new Date('1000-01-01');
    }
    $us->setProperty('Account_' . $account->getId() . '_LastTransferFormerFinishedTransactions', $now);
    if (!$lastInsertDate->before($now)) {
        return;
    }
    while ($currentTransaction = $account->getNextPlannedTransaction()) {
        transferFinishedTransactions($account, $currentTransaction, $lastInsertDate);
    }
}
function transferFormerFinishedTransactions($account)
{
    global $us;
    if ($us->getProperty('autoExpandPlannedTransactions') == false) {
        return;
    }
    $now = new Date();
    $now->setHour(0);
    $now->setMinute(0);
    $now->setSecond(0);
    $account->setType('planned');
    $account->setFilter(array(array('key' => 'beginDate', 'op' => 'le', 'val' => $now)));
    try {
        $lastInsertDate = $us->getProperty('Account_' . $account->getId() . '_LastTransferFormerFinishedTransactions');
    } catch (BadgerException $ex) {
        $lastInsertDate = new Date('1000-01-01');
    }
    $us->setProperty('Account_' . $account->getId() . '_LastTransferFormerFinishedTransactions', $now);
    if (!$lastInsertDate->before($now)) {
        return;
    }
    while ($currentTransaction = $account->getNextPlannedTransaction()) {
        $date = new Date($currentTransaction->getBeginDate());
        $dayOfMonth = $date->getDay();
        //While we are before now and the end date of this transaction
        while (!$date->after($now) && !$date->after(is_null($tmp = $currentTransaction->getEndDate()) ? new Date('9999-12-31') : $tmp)) {
            if ($date->after($lastInsertDate)) {
                $account->addFinishedTransaction($currentTransaction->getAmount(), $currentTransaction->getTitle(), $currentTransaction->getDescription(), new Date($date), $currentTransaction->getTransactionPartner(), $currentTransaction->getCategory(), $currentTransaction->getOutsideCapital(), false, true);
            }
            //do the date calculation
            switch ($currentTransaction->getRepeatUnit()) {
                case 'day':
                    $date->addSeconds($currentTransaction->getRepeatFrequency() * 24 * 60 * 60);
                    break;
                case 'week':
                    $date->addSeconds($currentTransaction->getRepeatFrequency() * 7 * 24 * 60 * 60);
                    break;
                case 'month':
                    //Set the month
                    $date = new Date(Date_Calc::endOfMonthBySpan($currentTransaction->getRepeatFrequency(), $date->getMonth(), $date->getYear(), '%Y-%m-%d'));
                    //And count back as far as the last valid day of this month
                    while ($date->getDay() > $dayOfMonth) {
                        $date->subtractSeconds(24 * 60 * 60);
                    }
                    break;
                case 'year':
                    $newYear = $date->getYear() + $currentTransaction->getRepeatFrequency();
                    if ($dayOfMonth == 29 && $date->getMonth() == 2 && !Date_Calc::isLeapYear($newYear)) {
                        $date->setDay(28);
                    } else {
                        $date->setDay($dayOfMonth);
                    }
                    $date->setYear($newYear);
                    break;
                default:
                    throw new BadgerException('Account', 'IllegalRepeatUnit', $currentTransaction->getRepeatUnit());
                    exit;
            }
        }
    }
}
/**
 * Returns the Account balance for $account at the end of each day between $startDate and $endDate.
 * 
 * Considers the planned transactions of $account.
 * 
 * @param object $account The Account object for which the balance should be calculated. 
 * It should be 'fresh', i. e. no transactions of any type should have been fetched from it.
 * @param object $startDate The first date the balance should be calculated for as Date object.
 * @param object $endDate The last date the balance should be calculated for as Date object.
 * @return array Array of Amount objects corresponding to the balance of $account at each day between
 * $startDate and $endDate. The array keys are the dates as ISO-String (yyyy-mm-dd). 
 */
function getDailyAmount($account, $startDate, $endDate, $isoDates = true, $startWithBalance = false, $includePlannedTransactions = false)
{
    global $badgerDb;
    $account->setTargetFutureCalcDate($endDate);
    $account->setOrder(array(array('key' => 'valutaDate', 'dir' => 'asc')));
    if (!$includePlannedTransactions) {
        $account->setType('finished');
    }
    $result = array();
    $startDate->setHour(0);
    $startDate->setMinute(0);
    $startDate->setSecond(0);
    $endDate->setHour(0);
    $endDate->setMinute(0);
    $endDate->setSecond(0);
    $currentDate = new Date($startDate);
    $currentAmount = new Amount();
    $firstRun = true;
    //foreach transaction
    while ($currentTransaction = $account->getNextTransaction()) {
        if ($currentDate->after($endDate)) {
            //we reached $endDAte
            break;
        }
        if ($firstRun && $startWithBalance) {
            $currentAmount = new Amount($currentTransaction->getBalance());
            $currentAmount->sub($currentTransaction->getAmount());
            $firstRun = false;
        }
        //fill all dates between last and this transaction with the old amount
        while (is_null($tmp = $currentTransaction->getValutaDate()) ? false : $currentDate->before($tmp)) {
            if ($isoDates) {
                $key = $currentDate->getDate();
            } else {
                $key = $currentDate->getTime();
            }
            $result[$key] = new Amount($currentAmount);
            $currentDate->addSeconds(24 * 60 * 60);
            if ($currentDate->after($endDate)) {
                //we reached $endDAte
                break;
            }
        }
        $currentAmount->add($currentTransaction->getAmount());
    }
    if ($firstRun && $startWithBalance) {
        $newAccountManager = new AccountManager($badgerDb);
        $newAccount = $newAccountManager->getAccountById($account->getId());
        $newAccount->setOrder(array(array('key' => 'valutaDate', 'dir' => 'asc')));
        while ($newTransaction = $newAccount->getNextTransaction()) {
            $currentDate = $newTransaction->getValutaDate();
            if ($currentDate->after($startDate)) {
                //we reached $endDAte
                break;
            }
            $currentAmount = new Amount($newTransaction->getBalance());
        }
        $currentDate = new Date($startDate);
        if ($isoDates) {
            $key = $currentDate->getDate();
        } else {
            $key = $currentDate->getTime();
        }
        $result[$key] = new Amount($currentAmount);
    }
    //fill all dates after the last transaction with the newest amount
    while (Date::compare($currentDate, $endDate) <= 0) {
        if ($isoDates) {
            $key = $currentDate->getDate();
        } else {
            $key = $currentDate->getTime();
        }
        $result[$key] = new Amount($currentAmount);
        $currentDate->addSeconds(24 * 60 * 60);
    }
    return $result;
}
示例#15
0
 /**
  * A method to get the most recent details of advertisement delivery for
  * a given list of advertisement/zone pairs set to deliver in the current
  * operation interval. Normally, the data will be retrieved from the previous
  * operation interval, but if no data exists for that ad/zone pair, then the
  * next previous operation interval will be tried, and so on, up to a limit
  * of MAX_PREVIOUS_AD_DELIVERY_INFO_LIMIT minutes. (The default is one week.)
  *
  * Requires that a current day/time (as a Date object) be registered
  * with the OA_ServiceLocator (as "now").
  *
  * Note: The logic of this method seems a little convoluted, and it is.
  * However, it needs to be. The reason being:
  *  - If an ad delivered in the previous operation interval, it should
  *    have a priority set in ad_zone_assoc. This should be the most
  *    recent entry in data_summary_ad_zone_assoc. So, the first step is
  *    to get the data for all ads that have delivered in the previous
  *    OI, and the associated prioritisation data.
  *  - If an ad did not deliver, the prioritisation data set in the
  *    previous OI is still needed, so the second step is to get those
  *    ads that had prioiritisation data set in the previous OI, but did
  *    not deliver.
  *  - Finally, as some ads are limited by hour (for example), we want to
  *    to be able to get past prioritisation data for ads that were
  *    disabled in the last OI, so, we need to look for ad/zone pairs
  *    that have not yet been found, and get BOTH the prioritisation and
  *    delivery data from the last OI when the ads were active in the
  *    zones.
  * This is why the method uses a complex, 3 step process!
  *
  * @access public
  * @param array $aCurrentZones An array of Zones, indexed by Zone ID, with each
  *                             Zone containing the Advert objects that are linked
  *                             to deliver in the zone, in the current operation
  *                             interval.
  * @return mixed An array of arrays of arrays, each one representing a set of
  *               ad/zone delivery information, indexed by ad ID and zone ID.
  *               Each sub-sub array, if present, has the format:
  *               array (
  *                  'ad_id'                         => integer
  *                  'zone_id'                       => integer
  *                  'required_impressions'          => integer
  *                  'requested_impressions'         => integer
  *                  'priority_factor'               => double
  *                  'past_zone_traffic_fraction'    => double
  *                  'impressions'                   => integer
  *               )
  *               Returns false when the current date/time is not set in the
  *               OA_ServiceLocator.
  */
 function &getPreviousAdDeliveryInfo($aCurrentZones)
 {
     OA::debug("  - Getting details of previous ad/zone delivery", PEAR_LOG_DEBUG);
     $aConf = $GLOBALS['_MAX']['CONF'];
     $oServiceLocator =& OA_ServiceLocator::instance();
     $oDate =& $oServiceLocator->get('now');
     if (!$oDate) {
         return false;
     }
     $aAds = array();
     $aZones = array();
     $aZonesAds = array();
     $aPastDeliveryResult = array();
     $aPastPriorityResult = array();
     $aNonDeliveringPastPriorityResult = array();
     $aFinalResult = array();
     // Obtain the earliest existing interval_start date found in the
     // data_summary_ad_zone_assoc table
     $table = $this->_getTablename('data_summary_ad_zone_assoc');
     $query = "\n            SELECT\n                interval_start AS interval_start\n            FROM\n                {$table}\n            ORDER BY\n                interval_start\n            LIMIT\n                1";
     $rc = $this->oDbh->query($query);
     if (!PEAR::isError($rc) && $rc->numRows() == 1) {
         $aRow = $rc->fetchRow();
         $oEarliestPastPriorityRecordDate = new Date($aRow['interval_start']);
         // Create a new date that is the limit number of minutes ago
         $oLimitDate = new Date();
         $oLimitDate->copy($oDate);
         $oLimitDate->subtractSeconds(MAX_PREVIOUS_AD_DELIVERY_INFO_LIMIT * 60);
         // Is the earliest date before this date?
         if ($oEarliestPastPriorityRecordDate->before($oLimitDate)) {
             // Use the limit date instead
             $oEarliestPastPriorityRecordDate = new Date();
             $oEarliestPastPriorityRecordDate->copy($oLimitDate);
         }
     }
     // Obtain the operation interval ID, and the start and end dates of the previous
     // operation interval
     $currentOperationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID($oDate);
     $previousOperationIntervalID = OX_OperationInterval::previousOperationIntervalID($currentOperationIntervalID);
     $aDates = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($oDate);
     // Obtain the ad ID, zone ID and number of impressions delivered for every ad/zone
     // combination that delivered impressions in the previous operation interval
     OA::debug("  - Getting details of ad/zone pairs that delivered last OI", PEAR_LOG_DEBUG);
     $table = $this->_getTablename('data_intermediate_ad');
     $query = "\n            SELECT\n                ad_id AS ad_id,\n                zone_id AS zone_id,\n                SUM(impressions) AS impressions\n            FROM\n                {$table}\n            WHERE\n                operation_interval = {$aConf['maintenance']['operationInterval']}\n                AND operation_interval_id = {$previousOperationIntervalID}\n                AND interval_start = '" . $aDates['start']->format('%Y-%m-%d %H:%M:%S') . "'\n                AND interval_end = '" . $aDates['end']->format('%Y-%m-%d %H:%M:%S') . "'\n                AND ad_id != 0\n                AND zone_id != 0\n            GROUP BY\n                ad_id,\n                zone_id\n            ORDER BY\n                ad_id,\n                zone_id";
     $rc = $this->oDbh->query($query);
     while ($aRow = $rc->fetchRow()) {
         // Store the ad ID as being one that has delivered
         $aAds[$aRow['ad_id']] = $aRow['ad_id'];
         // Store the zone ID as one that had impressions in it
         $aZones[$aRow['zone_id']] = $aRow['zone_id'];
         // Store the ad IDs by zone ID
         $aZonesAds[$aRow['zone_id']][$aRow['ad_id']] = true;
         // Store the impressions delivered for the ad/zone pair, and that the past
         // priority information for this ad/zone pair has not been found yet
         $aPastDeliveryResult[$aRow['ad_id']][$aRow['zone_id']]['impressions'] = $aRow['impressions'];
         $aPastDeliveryResult[$aRow['ad_id']][$aRow['zone_id']]['pastPriorityFound'] = false;
     }
     // Did any ads deliver last operation interval?
     if (!empty($aAds)) {
         // Is there past deliver data?
         if (isset($oEarliestPastPriorityRecordDate)) {
             // As all of the above ad/zone combinations delivered impressions in the previous
             // operation interval, a priority value must have existed. However, the priority
             // value may *not* have come from the previous interval, as maintenance may not
             // have been run (although it should have ;-)
             // However, just to be sure, interate backwards over past operation intervals
             // (up to the earliest existing record), obtaining the details of the impressions
             // requested and the priority values used for the above combinations
             $previousOperationIntervalIDLoop = $previousOperationIntervalID;
             $aDatesLoop = array();
             $aDatesLoop['start'] = new Date();
             $aDatesLoop['start']->copy($aDates['start']);
             $aDatesLoop['end'] = new Date();
             $aDatesLoop['end']->copy($aDates['end']);
             $foundAll = false;
             while (!$foundAll) {
                 if (!empty($aAds) && !empty($aZones)) {
                     $table = $this->_getTablename('data_summary_ad_zone_assoc');
                     $query = "\n                            SELECT\n                                ad_id AS ad_id,\n                                zone_id AS zone_id,\n                                required_impressions AS required_impressions,\n                                requested_impressions AS requested_impressions,\n                                to_be_delivered AS to_be_delivered,\n                                priority_factor AS priority_factor,\n                                past_zone_traffic_fraction AS past_zone_traffic_fraction,\n                                created AS created,\n                                expired AS expired\n                            FROM\n                                {$table}\n                            WHERE\n                                ad_id IN (" . implode(', ', $aAds) . ")\n                                AND zone_id IN (" . implode(', ', $aZones) . ")\n                                AND operation_interval = {$aConf['maintenance']['operationInterval']}\n                                AND operation_interval_id = {$previousOperationIntervalIDLoop}\n                                AND interval_start = '" . $aDatesLoop['start']->format('%Y-%m-%d %H:%M:%S') . "'\n                                AND interval_end = '" . $aDatesLoop['end']->format('%Y-%m-%d %H:%M:%S') . "'\n                            ORDER BY\n                                ad_id,\n                                zone_id";
                     $rc = $this->oDbh->query($query);
                     $aResult = $rc->fetchAll();
                     // Calculate the past priority results, using $aPastDeliveryResult in the call to
                     // _calculateAveragePastPriorityValues(), so that if this is the second (or greater)
                     // time this has been done then any ad/zone pairs that have come up with details for
                     // a second (or greater) time will NOT have their past priority info re-calculated
                     // with the wrong values
                     OA::debug('    - Getting past details of ad/zone pairs for OI starting at ' . $aDatesLoop['start']->format('%Y-%m-%d %H:%M:%S'), PEAR_LOG_DEBUG);
                     $this->_calculateAveragePastPriorityValues($aPastPriorityResult, $aResult, $oDate, $aPastDeliveryResult);
                     // Loop over the results, marking off the ad/zone combinations
                     // in the past delivery array as having had their past prioritisation
                     // information found and/or calculated
                     if (!empty($aPastPriorityResult)) {
                         foreach ($aPastPriorityResult as $a => $aAd) {
                             foreach ($aAd as $z => $aZone) {
                                 if ($aZone['pastPriorityFound']) {
                                     $aPastDeliveryResult[$a][$z]['pastPriorityFound'] = true;
                                 }
                             }
                         }
                     }
                 }
                 // Look over the past delivery array to see if there are any ad/zone
                 // combinations that do not yet have the past prioritisation information
                 $foundAll = true;
                 if (!empty($aPastDeliveryResult)) {
                     foreach ($aPastDeliveryResult as $a => $aAd) {
                         $remove = true;
                         foreach ($aAd as $z => $aZone) {
                             if (!$aPastDeliveryResult[$a][$z]['pastPriorityFound']) {
                                 if ($foundAll) {
                                     // Need to go back in time to look for more past priority info
                                     $previousOperationIntervalIDLoop = OX_OperationInterval::previousOperationIntervalID($previousOperationIntervalIDLoop);
                                     $aDatesLoop = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($aDatesLoop['start']);
                                     if (!$aDatesLoop['start']->before($oEarliestPastPriorityRecordDate)) {
                                         // Haven't exceeded earliest priority info date, so okay
                                         // to go ahead with going back in time...
                                         $foundAll = false;
                                     }
                                 }
                                 $remove = false;
                             }
                             // Remove the ad from the list of ads to select from next round,
                             // and check if this was the last ad in the zone, and, if so,
                             // also remove the zone from the list of zones to select from
                             // next round
                             if ($remove) {
                                 unset($aAds[$a]);
                                 unset($aZonesAds[$z][$a]);
                                 if (count($aZonesAds[$z]) == 0) {
                                     unset($aZones[$z]);
                                 }
                             }
                         }
                     }
                 }
             }
         }
         // Merge the past priority and delivery values into the final results array
         if (!empty($aPastDeliveryResult)) {
             foreach ($aPastDeliveryResult as $a => $aAd) {
                 foreach ($aAd as $z => $aZone) {
                     $aFinalResult[$a][$z] = array('ad_id' => $a, 'zone_id' => $z, 'required_impressions' => $aPastPriorityResult[$a][$z]['required_impressions'], 'requested_impressions' => $aPastPriorityResult[$a][$z]['requested_impressions'], 'to_be_delivered' => $aPastPriorityResult[$a][$z]['to_be_delivered'], 'priority_factor' => $aPastPriorityResult[$a][$z]['priority_factor'], 'past_zone_traffic_fraction' => $aPastPriorityResult[$a][$z]['past_zone_traffic_fraction'], 'impressions' => $aPastDeliveryResult[$a][$z]['impressions']);
                 }
             }
         }
     }
     // Select the details of all ad/zones that had required/requested impressions,
     // in the previous operation interval, but for which no impressions were delivered
     OA::debug('  - Getting details of ad/zone pairs that did not deliver last OI (but should have)', PEAR_LOG_DEBUG);
     $table1 = $this->_getTablename('data_summary_ad_zone_assoc');
     $table2 = $this->_getTablename('data_intermediate_ad');
     $query = "\n            SELECT\n                dsaza.ad_id AS ad_id,\n                dsaza.zone_id AS zone_id,\n                dsaza.required_impressions AS required_impressions,\n                dsaza.requested_impressions AS requested_impressions,\n                dsaza.to_be_delivered AS to_be_delivered,\n                dsaza.priority_factor AS priority_factor,\n                dsaza.past_zone_traffic_fraction AS past_zone_traffic_fraction,\n                dsaza.created AS created,\n                dsaza.expired AS expired\n            FROM\n                {$table1} AS dsaza\n            LEFT JOIN\n                {$table2} AS dia\n            ON\n                dsaza.ad_id = dia.ad_id\n                AND dsaza.zone_id = dia.zone_id\n                AND dsaza.operation_interval = dia.operation_interval\n                AND dsaza.operation_interval_id = dia.operation_interval_id\n                AND dsaza.interval_start = dia.interval_start\n                AND dsaza.interval_end = dia.interval_end\n            WHERE\n                dsaza.operation_interval = {$aConf['maintenance']['operationInterval']}\n                AND dsaza.operation_interval_id = {$previousOperationIntervalID}\n                AND dsaza.interval_start = '" . $aDates['start']->format('%Y-%m-%d %H:%M:%S') . "'\n                AND dsaza.interval_end = '" . $aDates['end']->format('%Y-%m-%d %H:%M:%S') . "'\n                AND dsaza.required_impressions > 0\n                AND dsaza.requested_impressions > 0\n                AND dia.ad_id IS NULL\n                AND dia.zone_id IS NULL\n            ORDER BY\n                ad_id,\n                zone_id";
     $rc = $this->oDbh->query($query);
     $aResult = $rc->fetchAll();
     // Calculate the past priority results, but without the optional parameter to
     // _calculateAveragePastPriorityValues(), as this is a single calculation on data
     // in the past OI, and no further looping back over time will occur
     OA::debug('  - Getting past details of the non-delivering ad/zone pairs', PEAR_LOG_DEBUG);
     $this->_calculateAveragePastPriorityValues($aNonDeliveringPastPriorityResult, $aResult, $oDate);
     // Merge the past priority values into the final results array
     if (!empty($aNonDeliveringPastPriorityResult)) {
         foreach ($aNonDeliveringPastPriorityResult as $a => $aAd) {
             foreach ($aAd as $z => $aZone) {
                 if (empty($aFinalResult[$a][$z])) {
                     $aFinalResult[$a][$z] = array('ad_id' => $a, 'zone_id' => $z, 'required_impressions' => $aNonDeliveringPastPriorityResult[$a][$z]['required_impressions'], 'requested_impressions' => $aNonDeliveringPastPriorityResult[$a][$z]['requested_impressions'], 'to_be_delivered' => $aNonDeliveringPastPriorityResult[$a][$z]['to_be_delivered'], 'priority_factor' => $aNonDeliveringPastPriorityResult[$a][$z]['priority_factor'], 'past_zone_traffic_fraction' => $aNonDeliveringPastPriorityResult[$a][$z]['past_zone_traffic_fraction']);
                 }
             }
         }
     }
     // Finally, now that all ad/zone combinations that had required/requested impressions
     // in the previous operation interval and delivered/didn't deliver have been dealt
     // with, check to see if there are any ad/zone combinations that are linked to
     // deliver in the current operation interval, which are not covered by the above
     OA::debug('  - Finding ad/zone pairs set to deliver, but with no past data yet', PEAR_LOG_DEBUG);
     $aAds = array();
     $aZones = array();
     $aZonesAds = array();
     $aNotInLastOIPastDeliveryResult = array();
     $aNotInLastOIPastPriorityResult = array();
     if (is_array($aCurrentZones) && !empty($aCurrentZones)) {
         foreach ($aCurrentZones as $zoneId => $oZone) {
             if (is_array($oZone->aAdverts) && !empty($oZone->aAdverts)) {
                 foreach ($oZone->aAdverts as $oAdvert) {
                     // Store that the past priority information for this ad/zone pair may
                     // not have yet been found
                     $aNotInLastOIPastDeliveryResult[$oAdvert->id][$zoneId]['pastPriorityFound'] = false;
                 }
             }
         }
     }
     // Remove those ad/zone pairs that have, in fact, already had their past priority
     // information found previously
     if (!empty($aFinalResult)) {
         foreach ($aFinalResult as $aResult) {
             if (isset($aResult['ad_id'])) {
                 unset($aNotInLastOIPastDeliveryResult[$aResult['ad_id']][$aResult['zone_id']]);
             }
         }
         foreach ($aNotInLastOIPastDeliveryResult as $adKey => $aTestZone) {
             if (empty($aTestZone)) {
                 unset($aNotInLastOIPastDeliveryResult[$adKey]);
             }
         }
     }
     // Create the sets of required ads and zones that need their past priority
     // information from older operation intervals found
     if (!empty($aNotInLastOIPastDeliveryResult)) {
         foreach ($aNotInLastOIPastDeliveryResult as $adKey => $aData) {
             // Store the ad ID as being one that needs to deliver
             $aAds[$adKey] = $adKey;
             foreach ($aData as $zoneKey => $value) {
                 // Store the zone ID as one that has an ad that needs to deliver in it
                 $aZones[$zoneKey] = $zoneKey;
                 // Store the ad IDs by zone ID
                 $aZonesAds[$zoneKey][$adKey] = true;
             }
         }
     }
     // Are there any ad/zone pairs that need data?
     if (!empty($aNotInLastOIPastDeliveryResult)) {
         // Is there past delivery data?
         if (isset($oEarliestPastPriorityRecordDate)) {
             // Loop over the previous operation intervals, starting with the one
             // *before* last, and find when (if possible) these ad/zone pairs
             // last *requested* to deliver; it doesn't matter if they did deliver
             // in that operation interval or not
             $previousOperationIntervalIDLoop = OX_OperationInterval::previousOperationIntervalID($previousOperationIntervalID);
             $aDatesLoop = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($aDates['start']);
             $foundAll = false;
             while (!$foundAll) {
                 if (!empty($aAds) && !empty($aZones)) {
                     $table = $this->_getTablename('data_summary_ad_zone_assoc');
                     $query = "\n                            SELECT\n                                ad_id AS ad_id,\n                                zone_id AS zone_id,\n                                required_impressions AS required_impressions,\n                                requested_impressions AS requested_impressions,\n                                to_be_delivered AS to_be_delivered,\n                                priority_factor AS priority_factor,\n                                past_zone_traffic_fraction AS past_zone_traffic_fraction,\n                                created AS created,\n                                expired AS expired,\n                                operation_interval AS operation_interval,\n                                operation_interval_id AS operation_interval_id,\n                                interval_start AS interval_start,\n                                interval_end AS interval_end\n                            FROM\n                                {$table}\n                            WHERE\n                                ad_id IN (" . implode(', ', $aAds) . ")\n                                AND zone_id IN (" . implode(', ', $aZones) . ")\n                                AND operation_interval = {$aConf['maintenance']['operationInterval']}\n                                AND operation_interval_id = {$previousOperationIntervalIDLoop}\n                                AND interval_start = '" . $aDatesLoop['start']->format('%Y-%m-%d %H:%M:%S') . "'\n                                AND interval_end = '" . $aDatesLoop['end']->format('%Y-%m-%d %H:%M:%S') . "'\n                            ORDER BY\n                                ad_id,\n                                zone_id";
                     $rc = $this->oDbh->query($query);
                     $aResult = $rc->fetchAll();
                     // Calculate the past priority results, using $aNotInLastOIPastDeliveryResult in the
                     // call to _calculateAveragePastPriorityValues(), so that if this is the second
                     // (or greater) time this has been done then any ad/zone pairs that have come up
                     // with details for a second (or greater) time will NOT have their past priority info
                     // re-calculated
                     OA::debug("    - Getting past details of ad/zone pairs which didn't deliver last OI, for OI " . "starting at " . $aDatesLoop['start']->format('%Y-%m-%d %H:%M:%S'), PEAR_LOG_DEBUG);
                     $this->_calculateAveragePastPriorityValues($aNotInLastOIPastPriorityResult, $aResult, $oDate, $aNotInLastOIPastDeliveryResult);
                     // Loop over the results, marking off the ad/zone combinations
                     // in the past delivery array as having had their past prioritisation
                     // information found and/or calculated
                     if (!empty($aNotInLastOIPastPriorityResult)) {
                         foreach ($aNotInLastOIPastPriorityResult as $a => $aAd) {
                             foreach ($aAd as $z => $aZone) {
                                 if ($aZone['pastPriorityFound']) {
                                     $aNotInLastOIPastDeliveryResult[$a][$z]['pastPriorityFound'] = true;
                                 }
                             }
                         }
                     }
                     // Look over the past delivery array to see if there are any ad/zone
                     // combinations that do not yet have the past prioritisation information
                     $foundAll = true;
                     if (!empty($aNotInLastOIPastDeliveryResult)) {
                         foreach ($aNotInLastOIPastDeliveryResult as $a => $aAd) {
                             $remove = true;
                             foreach ($aAd as $z => $aZone) {
                                 if (!$aNotInLastOIPastDeliveryResult[$a][$z]['pastPriorityFound']) {
                                     if ($foundAll) {
                                         // Need to go back in time to look for more past priority info
                                         $previousOperationIntervalIDLoop = OX_OperationInterval::previousOperationIntervalID($previousOperationIntervalIDLoop);
                                         $aDatesLoop = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($aDatesLoop['start']);
                                         if (!$aDatesLoop['start']->before($oEarliestPastPriorityRecordDate)) {
                                             // Haven't exceeded earliest priority info date, so okay
                                             // to go ahead with going back in time...
                                             $foundAll = false;
                                         }
                                     }
                                     $remove = false;
                                 }
                                 // Remove the ad from the list of ads to select from next round,
                                 // and check if this was the last ad in the zone, and, if so,
                                 // also remove the zone from the list of zones to select from
                                 // next round
                                 if ($remove) {
                                     unset($aAds[$a]);
                                     unset($aZonesAds[$z][$a]);
                                     if (count($aZonesAds[$z]) == 0) {
                                         unset($aZones[$z]);
                                     }
                                 }
                             }
                         }
                     }
                 } else {
                     $foundAll = true;
                 }
             }
         }
         // Now that it is known when (if) the remaining ads last requested to deliver,
         // determine how many impressions were delivered (if any) during the appropriate
         // operation intervals
         if (!empty($aNotInLastOIPastPriorityResult)) {
             foreach ($aNotInLastOIPastPriorityResult as $a => $aAd) {
                 foreach ($aAd as $z => $aZone) {
                     $table = $this->_getTablename('data_intermediate_ad');
                     $query = "\n                            SELECT\n                                SUM(impressions) AS impressions\n                            FROM\n                                {$table}\n                            WHERE\n                                operation_interval = {$aNotInLastOIPastPriorityResult[$a][$z]['operation_interval']}\n                                AND operation_interval_id = {$aNotInLastOIPastPriorityResult[$a][$z]['operation_interval_id']}\n                                AND interval_start = '{$aNotInLastOIPastPriorityResult[$a][$z]['interval_start']}'\n                                AND interval_end = '{$aNotInLastOIPastPriorityResult[$a][$z]['interval_end']}'\n                                AND ad_id = {$a}\n                                AND zone_id = {$z}";
                     $rc = $this->oDbh->query($query);
                     $aResult = $rc->fetchAll();
                     if (isset($aResult[0]['impressions'])) {
                         $aNotInLastOIPastPriorityResult[$a][$z]['impressions'] = $aResult[0]['impressions'];
                     }
                 }
             }
         }
         // Merge the past priority and delivery values into the final results array
         if (!empty($aNotInLastOIPastPriorityResult)) {
             foreach ($aNotInLastOIPastPriorityResult as $a => $aAd) {
                 foreach ($aAd as $z => $aZone) {
                     if (empty($aFinalResult[$a][$z])) {
                         $aFinalResult[$a][$z] = array('ad_id' => $a, 'zone_id' => $z, 'required_impressions' => $aNotInLastOIPastPriorityResult[$a][$z]['required_impressions'], 'requested_impressions' => $aNotInLastOIPastPriorityResult[$a][$z]['requested_impressions'], 'to_be_delivered' => $aNotInLastOIPastPriorityResult[$a][$z]['to_be_delivered'], 'priority_factor' => $aNotInLastOIPastPriorityResult[$a][$z]['priority_factor'], 'past_zone_traffic_fraction' => $aNotInLastOIPastPriorityResult[$a][$z]['past_zone_traffic_fraction']);
                         if (isset($aNotInLastOIPastPriorityResult[$a][$z]['impressions'])) {
                             $aFinalResult[$a][$z]['impressions'] = $aNotInLastOIPastPriorityResult[$a][$z]['impressions'];
                         }
                     }
                 }
             }
         }
     }
     return $aFinalResult;
 }
示例#16
0
 /**
  * A method to check if the campaign is awaiting activation
  *
  * @return bool
  */
 function _isAwaiting()
 {
     static $oServiceLocator;
     if (!empty($this->activate_time) && $this->activate_time != OX_DATAOBJECT_NULL) {
         if (!isset($oServiceLocator)) {
             $oServiceLocator =& OA_ServiceLocator::instance();
         }
         if (!($oNow = $oServiceLocator->get('now'))) {
             $oNow = new Date();
         }
         $oNow->toUTC();
         $oActivate = new Date($this->activate_time);
         $oActivate->setTZbyID('UTC');
         if ($oNow->before($oActivate)) {
             return true;
         }
     }
     return false;
 }
示例#17
0
 /**
  * A private method to caclucate the number of days left until a
  * campaign expires based on the impression, click or conversion
  * delivery targets & the delivery rate of the campaign to date.
  *
  * @param array $aDeliveryData An array of two items. "delivered":
  *                             the number of impressions, clicks or
  *                             conversions delivered so far; and
  *                             "day_of_first": a string in YYYY-MM-DD
  *                             format representing the day that the
  *                             first impression, click or conversion
  *                             was delivered.
  * @param integer $target      The total number of impressions, clicks
  *                             or conversions required to be delivered
  *                             by the campaign.
  * @return array An array of three items. "daysLeft": the estimated
  *               number of days remaining until the campaign ends;
  *               "date": the estimated date of expiration; and "date_f"
  */
 function _calculateRemainingDays($aDeliveryData, $target)
 {
     global $date_format;
     $oNowDate = new Date();
     $aExpiration = array();
     // How many days since the first impression/click/conversion?
     if (!empty($aDeliveryData['day_of_first'])) {
         $oFirstDate = new Date($aDeliveryData['day_of_first']);
         $oSpan = new Date_Span();
         $oSpan->setFromDateDiff($oFirstDate, $oNowDate);
         $daysSinceFirst = ceil($oSpan->toDays());
     } else {
         $daysSinceFirst = 1;
     }
     // Have *any* impressions/clicks/conversions been delivered?
     if (!empty($aDeliveryData["delivered"]) && $aDeliveryData["delivered"] > 0) {
         $targetRemaining = $target - $aDeliveryData["delivered"];
         $deliveryRate = $aDeliveryData["delivered"] / $daysSinceFirst;
         $daysLeft = (int) round($targetRemaining / $deliveryRate);
         $oSpan = new Date_Span();
         $oSpan->setFromDays($daysLeft);
         $oEstimatedEndDate = new Date();
         $oEstimatedEndDate->addSpan($oSpan);
         if ($oEstimatedEndDate->before($oNowDate)) {
             // Ooop! Wrapped into the past - get the biggest possible date
             $oEstimatedEndDate = new Date('1960-01-01 00:00:00');
             $oEstimatedEndDate->subtractSeconds(1);
         }
         $estimatedEndDateFormat = $oEstimatedEndDate->format($date_format);
         $aExpiration = array('daysLeft' => $daysLeft, 'date_f' => $estimatedEndDateFormat, 'date' => $oEstimatedEndDate);
     }
     return $aExpiration;
 }
示例#18
0
 /**
  * A method to check if midnight tasks should run
  *
  * @param Date $oLastRun
  * @return boolean
  */
 function isMidnightMaintenance($oLastRun)
 {
     global $serverTimezone;
     if (empty($oLastRun)) {
         return true;
     }
     $oServiceLocator =& OA_ServiceLocator::instance();
     $lastMidnight = new Date($oServiceLocator->get('now'));
     if (!empty($serverTimezone)) {
         $lastMidnight->convertTZbyID($serverTimezone);
     }
     $lastMidnight->setHour(0);
     $lastMidnight->setMinute(0);
     $lastMidnight->setSecond(0);
     $oLastRunCopy = new Date($oLastRun);
     return $oLastRunCopy->before($lastMidnight);
 }
示例#19
0
function create_history($connection, $template)
{
    $userid = getUserID($connection);
    $yearmoday = explode("-", $_SESSION["nav_month"]);
    // See if the users is trying to display a month other than the current month.
    if ($yearmoday != NULL) {
        $display_mo = new Date();
        $display_mo->setDayMonthYear($yearmoday[2], $yearmoday[1], $yearmoday[0]);
    } else {
        $display_mo = new Date();
    }
    $LastDay = $display_mo->getYear() . "-" . $display_mo->getMonth() . "-" . $display_mo->GetDaysInMonth();
    $FirstDay = $display_mo->format("%Y") . "-" . $display_mo->format("%m") . "-" . "1";
    $sbr_type = array("s", "b", "r");
    $total_duration = array(0, 0, 0);
    $total_distance = array(0, 0, 0);
    $total_calories = array(0, 0, 0);
    $i = 0;
    while ($i < 3) {
        $query = "SELECT * FROM flmain WHERE user_id={$userid} AND workout_date>='" . $FirstDay . "' AND workout_date<='" . $LastDay . "' AND sbr_type='" . $sbr_type[$i] . "' ORDER BY workout_date ASC";
        $result = @mysql_query($query, $connection);
        if (mysql_num_rows($result) > 0) {
            //set the correct template block
            selectActivityBlock($i, $template);
            //Get the first row of data and compare it to the day of the month to see if we have any
            //data to display on the current day.
            $row = mysql_fetch_array($result);
            //Out put each day of the displayed month. If we have data for that day
            //then put it into the grid also.
            $currentDay = new Date();
            $nextMonth = new Date();
            $currentDay->setDayMonthYear(1, $display_mo->getMonth(), $display_mo->getYear());
            //Move the display_mo to the first day of the next month.
            $nextMonth->setDayMonthYear($display_mo->GetDaysInMonth(), $display_mo->getMonth(), $display_mo->getYear());
            $nextMonth->addDays(1);
            while ($currentDay->before($nextMonth)) {
                // select the correct activity block.
                selectActivityBlock($i, $template);
                $template->setVariable("UPDATE", $currentDay->format("%Y-%m-%d"));
                $template->setVariable("DATE", $currentDay->format("%b %e, %Y"));
                //Check to see if the current day matches the current row, if so then output it.
                if (!strcmp($currentDay->format("%Y-%m-%d"), $row["workout_date"])) {
                    outputCurrentDay($template, $row, $i);
                    //Add up the duration, distance and calories
                    $total_dur[$i] = $total_dur[$i] + convert_time_seconds($row["duration"]);
                    $total_dist[$i] = $total_dist[$i] + $row["distance"];
                    $total_cal[$i] = $total_cal[$i] + $row["cals_burned"];
                    $row = mysql_fetch_array($result);
                }
                $template->parseCurrentBlock();
                $currentDay->addDays(1);
            }
            outputTotals($template, $total_dur[$i], $total_dist[$i], $total_cal[$i], $i);
        } else {
            $currentDay = new Date();
            $nextMonth = new Date();
            $currentDay->setDayMonthYear(1, $display_mo->getMonth(), $display_mo->getYear());
            //Move the display_mo to the first day of the next month.
            $nextMonth->setDayMonthYear($display_mo->GetDaysInMonth(), $display_mo->getMonth(), $display_mo->getYear());
            $nextMonth->addDays(1);
            while ($currentDay->before($nextMonth)) {
                // set the correct activity block.
                selectActivityBlock($i, $template);
                $template->setVariable("UPDATE", $currentDay->format("%Y-%m-%d"));
                $template->setVariable("DATE", $currentDay->format("%b %e, %Y"));
                $template->parseCurrentBlock();
                $currentDay->addDays(1);
            }
        }
        $i = $i + 1;
    }
}