/** * A mathod to quickly check the data in the database for the date * range given, to ensure that the range being tested & corrected * seems reasonable. * * @param Date $oStartDate The start date/time of the range to test & correct. * @param Date $oEndDate The end date/time of the range to test & correct. * @return boolean True if the date range seems okay, false otherwise. */ function checkRangeData($oStartDate, $oEndDate) { // Test that there are no rows in the data_intermediate_ad table where the // operation interval value does not match that in the configuration file $doData_intermediate_ad = OA_Dal::factoryDO('data_intermediate_ad'); $doData_intermediate_ad->whereAdd('date_time >= ' . $this->oDbh->quote($oStartDate->format('%Y-%m-%d %H:%M:%S'), 'timestamp')); $doData_intermediate_ad->whereAdd('date_time <= ' . $this->oDbh->quote($oEndDate->format('%Y-%m-%d %H:%M:%S'), 'timestamp')); $doData_intermediate_ad->whereAdd('operation_interval != ' . $this->oDbh->quote(OX_OperationInterval::getOperationInterval(), 'integer')); $doData_intermediate_ad->find(); $rows = $doData_intermediate_ad->getRowCount(); if ($rows > 0) { $message = "\n Detected at least one row in the data_intermediate_ad table with operation interval != " . OX_OperationInterval::getOperationInterval() . ".\n"; echo $message; return false; } // Test that all of the date/time values in the data_summary_ad_hourly // table align with the start of operation intervals $doData_summary_ad_hourly = OA_Dal::factoryDO('data_summary_ad_hourly'); $doData_summary_ad_hourly->selectAdd(); $doData_summary_ad_hourly->selectAdd('DISTINCT date_time'); $doData_summary_ad_hourly->whereAdd('date_time >= ' . $this->oDbh->quote($oStartDate->format('%Y-%m-%d %H:%M:%S'), 'timestamp')); $doData_summary_ad_hourly->whereAdd('date_time <= ' . $this->oDbh->quote($oEndDate->format('%Y-%m-%d %H:%M:%S'), 'timestamp')); $doData_summary_ad_hourly->find(); while ($doData_summary_ad_hourly->fetch()) { $oDate = new Date($doData_summary_ad_hourly->date_time); $result = OX_OperationInterval::checkDateIsStartDate($oDate); if (!$result) { $message = "\n Detected at least one row in the data_summary_ad_hourly table with date_time value not on the hour start interval.\n"; echo $message; return false; } } return true; }
/** * A method to test the getOperationInterval() method. */ function testGetOperationInterval() { $this->assertEqual(OX_OperationInterval::getOperationInterval(), $GLOBALS['_MAX']['CONF']['maintenance']['operationInterval']); }
require_once OX_PATH . '/lib/pear/Date.php'; // Standard messages $haltMessage = "\nThe {$scriptName} script will NOT be run.\n\n"; if ($argc !== 2) { echo "\nRequires the hostname to be passed in as a string, as per the standard maintenance CLI script.\n"; echo $haltMessage; exit; } if (!defined('INTERVAL_START') || !defined('INTERVAL_END')) { echo "\nPlease ensure that you have read the comments in the {$scriptName} script.\n\nYou will also find out how to make this script work by reading the comments. :-)\n"; echo $haltMessage; exit; } // Initialise the script RV::disableErrorHandling(); $result = OX_OperationInterval::checkOperationIntervalValue(OX_OperationInterval::getOperationInterval()); RV::enableErrorHandling(); if (PEAR::isError($result)) { $message = "\nThe operation interval in your OpenX configuration file is not valid. Please see the OpenX\ndocumentation for more details on valid operation interval values.\n"; echo $message; echo $haltMessage; exit; } $oStartDate = new Date(INTERVAL_START); $result = OX_OperationInterval::checkDateIsStartDate($oStartDate); if (!$result) { $message = "\nThe start date defined in the {$scriptName} script is not a valid operation interval start date.\nPlease edit the statisticsTestAndCorrect.php script before running.\n"; echo $message; echo $haltMessage; exit; }
/** * A private method that determines which (if any) operation intervals need the zone * impression forecast values to be updated for ALL zones. * * @access private * @return mixed One of the following three values will be returned, depending on what * ZIF values need to be updated: * - true: Update the ZIF values for all operation intervals. * - false: No ZIF values need to be updated (eg. this is the second, or greater, * time that the MPE has been run in this operation interval, so there * are no new statistics values summarised by the MSE to allow the ZIF * values to be udpated). * - array: An array with the start and end operation interval IDs of the * range to update; the first may be higher than the second, in * the event that the range spans from the end of one week into the * start of the next week. */ function _getUpdateTypeRequired() { OA::debug('- Calculating range of operation intervals which require ZIF update', PEAR_LOG_DEBUG); // Set default return value $return = false; if (is_null($this->oStatisticsUpdatedToDate)) { // The MSE has never been run; there are no stats. Update all operation intervals (with the // default zone forecast value) so that this new installation of OpenX can ran: return true OA::debug(' - No previous maintenance statisitcs run, so update all OIs required', PEAR_LOG_DEBUG); $return = true; } elseif (is_null($this->oPriorityUpdatedToDate)) { // The MPE has never updated zone forecasts before. Update all operation intervals (with the // default zone forecast value) so that this new installation of OpenX can ran: return true OA::debug(' - No previous maintenance priority run, so update all OIs required', PEAR_LOG_DEBUG); $return = true; } elseif (OX_OperationInterval::getOperationInterval() != $this->priorityOperationInterval) { // The operation interval has changed since the last run, force an update all: return true OA::debug(' - OPERATION INTERVAL LENGTH CHANGE SINCE LAST RUN', PEAR_LOG_DEBUG); OA::debug(' - Update of all OIs required', PEAR_LOG_DEBUG); $return = true; } else { // If stats was run after priority, then the maintenance stats updated to date will be equal to, // or after, the maintenance priority updated to date (as the maintenance priority updated to // date is one operation interval ahead of where statistics is) if ($this->oStatisticsUpdatedToDate->equals($this->oPriorityUpdatedToDate) || $this->oStatisticsUpdatedToDate->after($this->oPriorityUpdatedToDate)) { // If a week or more has passed since the last priority update, update all: return true $oSpan = new Date_Span(); $oUpdatedToDateCopy = new Date(); $oUpdatedToDateCopy->copy($this->oPriorityUpdatedToDate); $oDateNowCopy = new Date(); $oDateNowCopy->copy($this->oDateNow); $oSpan->setFromDateDiff($oUpdatedToDateCopy, $oDateNowCopy); if ($oSpan->day >= 7) { OA::debug(' - One week has passed since last run, so update all OIs required', PEAR_LOG_DEBUG); $return = true; } else { // Get the operation intervals for each run $statsOpIntId = OX_OperationInterval::convertDateToOperationIntervalID($this->oStatisticsUpdatedToDate); $priorityOpIntId = OX_OperationInterval::convertDateToOperationIntervalID($this->oPriorityUpdatedToDate); // Always predict one interval ahead of the statistics engine $statsOpIntId = OX_OperationInterval::nextOperationIntervalID($statsOpIntId); // As long as the operation intervals are not in the same interval, priority should be run if ($statsOpIntId != $priorityOpIntId) { OA::debug(' - Found OI range to update', PEAR_LOG_DEBUG); $return = array($priorityOpIntId, $statsOpIntId); } else { OA::debug(' - MPE has already run this operation interval, no ZIF update required', PEAR_LOG_DEBUG); $return = false; } } } } return $return; }
/** * A method to get the number of operation intervals in a given * start & end date range must be valid OI start & end date range * * @static * @param object $oStartDate PEAR::Date object * @param object $oEndDate PEAR::Date object * @return integer number of operation intervals remaining */ function getIntervalsRemaining($oStartDate, $oEndDate) { $operationIntervalSeconds = OX_OperationInterval::getOperationInterval() * 60; // Convert to UTC $oStartCopy = new Date($oStartDate); $oStartCopy->toUTC(); $oEndCopy = new Date($oEndDate); $oEndCopy->toUTC(); // Get timestamp of start date/time - in seconds $startDateSeconds = mktime($oStartCopy->getHour(), $oStartCopy->getMinute(), $oStartCopy->getSecond(), $oStartCopy->getMonth(), $oStartCopy->getDay(), $oStartCopy->getYear()); // Get timestamp of end date/time - in seconds $endDateSeconds = mktime($oEndCopy->getHour(), $oEndCopy->getMinute(), $oEndCopy->getSecond(), $oEndCopy->getMonth(), $oEndCopy->getDay(), $oEndCopy->getYear()); // calculate interval length in seconds $interval = $endDateSeconds - $startDateSeconds; // find number of operation intervals during interval return $interval <= 0 ? 0 : round($interval / $operationIntervalSeconds); }
function _getOperationIntervalInfo(&$operationIntervalId, &$operationInterval, &$dateStart, &$dateEnd) { $date = new Date(); $operationInterval = new OX_OperationInterval(); $operationIntervalId = $operationInterval->convertDateToOperationIntervalID($date); $operationInterval = OX_OperationInterval::getOperationInterval(); $aOperationIntervalDates = OX_OperationInterval::convertDateToOperationIntervalStartAndEndDates($date); $dateStart = DBC::makeLiteral($aOperationIntervalDates['start']->format(TIMESTAMP_FORMAT)); $dateEnd = DBC::makeLiteral($aOperationIntervalDates['end']->format(TIMESTAMP_FORMAT)); }
/** * A method to return the forecast impressions for a zone, indexed by operation interval, * from the current operation interval through the past week. If no forecast stored in * the database for a given OI, uses average of forecasts found. * * @param integer $zoneId The Zone ID. * @return mixed An array on success, false on failure. The array is of the format: * array( * [operation_interval_id] => array( * ['zone_id'] => zone_id, * ['_impressions'] => forecast_impressions, * ['operation_interval_id'] => operation_interval_id * ) * [operation_interval_id] => array( * ['zone_id'] => zone_id, * ['forecast_impressions'] => forecast_impressions, * ['operation_interval_id'] => operation_interval_id * ) * . * . * . * ) */ function getPreviousWeekZoneForcastImpressions($zoneId) { if (empty($zoneId) || !is_numeric($zoneId)) { OA::debug('Invalid zone ID argument', PEAR_LOG_ERR); return false; } $aConf = $GLOBALS['_MAX']['CONF']; $oServiceLocator =& OA_ServiceLocator::instance(); $oDate =& $oServiceLocator->get('now'); if (!$oDate) { return false; } // Get previous OI $oPreviousOI = new Date($oDate); $oPreviousOI->subtractSeconds(OX_OperationInterval::getOperationInterval() * 60); // Get the start and end ranges of the current week, up to the previous OI $aDates = OX_OperationInterval::convertDateToOperationIntervalStartAndEndDates($oPreviousOI); $oDateWeekStart = new Date(); $oDateWeekStart->copy($aDates['end']); $oDateWeekStart->subtractSeconds(SECONDS_PER_WEEK - 1); $oDateWeekEnd = new Date(); $oDateWeekEnd->copy($aDates['end']); // Select the zone forecasts from the database $tableName = $this->_getTablename('data_intermediate_ad'); $oneHourInterval = OA_Dal::quoteInterval(1, 'hour'); $query = "\n SELECT\n SUM(impressions) AS forecast_impressions,\n operation_interval_id AS operation_interval_id,\n interval_start AS interval_start,\n interval_end AS interval_end\n FROM\n {$tableName}\n WHERE\n zone_id = {$zoneId}\n AND operation_interval = {$aConf['maintenance']['operationInterval']}\n AND interval_start >= '" . $oDateWeekStart->format('%Y-%m-%d %H:%M:%S') . "'\n AND interval_end <= '" . $oDateWeekEnd->format('%Y-%m-%d %H:%M:%S') . "'\n AND date_time > DATE_SUB('" . $oDateWeekStart->format('%Y-%m-%d %H:%M:%S') . "', {$oneHourInterval})\n AND date_time < DATE_ADD('" . $oDateWeekEnd->format('%Y-%m-%d %H:%M:%S') . "', {$oneHourInterval})\n AND zone_id != 0\n GROUP BY\n \tinterval_start,\n \tinterval_end,\n \toperation_interval_id\n ORDER BY\n interval_start"; $rc = $this->oDbh->query($query); $totalForecastImpressions = 0; $count = 0; if (!PEAR::isError($rc)) { // Sort the results into an array indexed by the operation interval ID $aFinalResult = array(); while ($aRow = $rc->fetchRow()) { $aFinalResult[$aRow['operation_interval_id']] = array('zone_id' => $zoneId, 'forecast_impressions' => $aRow['forecast_impressions'], 'operation_interval_id' => $aRow['operation_interval_id']); $count++; $totalForecastImpressions += $aRow['forecast_impressions']; } } $averageForecastImpressions = 0; if ($count > 0) { $averageForecastImpressions = floor($totalForecastImpressions / $count); } if ($averageForecastImpressions == 0) { $averageForecastImpressions = $this->getZoneForecastDefaultZoneImpressions(); } // Check each operation interval ID has a forecast impression value, // and if not, set to the system default. for ($operationIntervalID = 0; $operationIntervalID < OX_OperationInterval::operationIntervalsPerWeek(); $operationIntervalID++) { if (!isset($aFinalResult[$operationIntervalID])) { $aFinalResult[$operationIntervalID] = array('zone_id' => $zoneId, 'forecast_impressions' => $averageForecastImpressions, 'operation_interval_id' => $operationIntervalID); } } // Overwrite current OI with previous OI to match the zone forecasting algorithm $currOI = OX_OperationInterval::convertDateToOperationIntervalID($oDate); $prevOI = OX_OperationInterval::previousOperationIntervalID($currOI); $aFinalResult[$currOI]['forecast_impressions'] = $aFinalResult[$prevOI]['forecast_impressions']; // Return data return $aFinalResult; }