/**
  * A private method for summarising data into the final tables when
  * at least one hour is complete.
  *
  * @access private
  * @param PEAR::Date $oStartDate The start date of the complete hour(s).
  * @param PEAR::Date $oEndDate The end date of the complete hour(s).
  */
 function _saveSummary($oStartDate, $oEndDate)
 {
     $message = '- Updating the data_summary_ad_hourly table for data after ' . $oStartDate->format('%Y-%m-%d %H:%M:%S') . ' ' . $oStartDate->tz->getShortName();
     $this->oController->report .= $message . ".\n";
     OA::debug($message, PEAR_LOG_DEBUG);
     $oServiceLocator =& OA_ServiceLocator::instance();
     $oDal =& $oServiceLocator->get('OX_Dal_Maintenance_Statistics');
     $aTypes = array('types' => array(0 => 'request', 1 => 'impression', 2 => 'click'), 'connections' => array(1 => MAX_CONNECTION_AD_IMPRESSION, 2 => MAX_CONNECTION_AD_CLICK));
     $oDal->saveSummary($oStartDate, $oEndDate, $aTypes, 'data_intermediate_ad', 'data_summary_ad_hourly');
 }
 /**
  * A method to determine the number of impressions, clicks and conversions
  * delivered by a given ecpm campaign to date.
  *
  * Can also determine the delivery information up to a given operation
  * interval end date.
  *
  * @param integer    $agencyId The agency ID.
  * @param PEAR::Date $oDate      Limits delivery information to that which is
  *                               after this date.
  * @param integer    $priority Campaign priority (by default eCPM priority).
  * @return array
  */
 function getDeliveredEcpmCampainImpressionsByAgency($agencyId, $oDate, $priority = null)
 {
     $prefix = $this->getTablePrefix();
     $oDbh = OA_DB::singleton();
     if (is_null($priority)) {
         $priority = DataObjects_Campaigns::PRIORITY_ECPM;
     }
     $query = "\n            SELECT\n                c.campaignid AS campaignid,\n                SUM(dia.impressions) AS impressions_delivered\n            FROM\n                {$oDbh->quoteIdentifier($prefix . 'clients', true)} AS cl,\n                {$oDbh->quoteIdentifier($prefix . 'campaigns', true)} AS c,\n                {$oDbh->quoteIdentifier($prefix . 'banners', true)} AS b,\n                {$oDbh->quoteIdentifier($prefix . 'data_intermediate_ad', true)} AS dia\n            WHERE\n                cl.agencyid = " . DBC::makeLiteral($agencyId) . "\n                AND c.status = " . OA_ENTITY_STATUS_RUNNING . "\n                AND c.priority = " . $priority . "\n                AND cl.clientid = c.clientid\n                AND b.bannerid = dia.ad_id\n                AND b.campaignid = c.campaignid\n                AND dia.interval_end >= '" . $oDate->format('%Y-%m-%d %H:%M:%S') . "'\n            GROUP BY\n                c.campaignid";
     $rs = DBC::NewRecordSet($query);
     if (PEAR::isError($rs)) {
         return false;
     }
     return $rs->getAll(array(), 'campaignid');
 }
 /**
  * A method to reject conversions which variables which are required to be
  * non-empty, but which are in reality, empty, between the supplied operation
  * interval start and end dates.
  *
  * @param PEAR::Date $oStart The start date/time of the operation interval.
  * @param PEAR::Date $oEnd   The end date/time of the operation interval.
  */
 function rejectEmptyVarConversions($oStart, $oEnd)
 {
     $aConf = $GLOBALS['_MAX']['CONF'];
     $var = $this->oDbh->quoteIdentifier($aConf['table']['prefix'] . $aConf['table']['variables'], true);
     $diac = $this->oDbh->quoteIdentifier($aConf['table']['prefix'] . $aConf['table']['data_intermediate_ad_connection'], true);
     $diavv = $this->oDbh->quoteIdentifier($aConf['table']['prefix'] . $aConf['table']['data_intermediate_ad_variable_value'], true);
     $query = "\n            UPDATE\n                {$diac}\n            SET\n                connection_status = " . MAX_CONNECTION_STATUS_DISAPPROVED . ",\n                updated = '" . OA::getNow() . "',\n                comments = 'Rejected because ' || COALESCE(NULLIF(v.description, ''), v.name) || ' is empty'\n            FROM\n                {$diac} AS diac2\n            JOIN\n                {$var} AS v\n            ON\n                (\n                    diac2.tracker_id = v.trackerid\n                )\n            LEFT JOIN\n                {$diavv} AS diavv\n            ON\n                (\n                    diac2.data_intermediate_ad_connection_id = diavv.data_intermediate_ad_connection_id\n                    AND\n                    v.variableid = diavv.tracker_variable_id\n                )\n            WHERE\n                {$diac}.data_intermediate_ad_connection_id = diac2.data_intermediate_ad_connection_id\n                AND\n                {$diac}.tracker_date_time >= '" . $oStart->format('%Y-%m-%d %H:%M:%S') . "'\n                AND\n                {$diac}.tracker_date_time <= '" . $oEnd->format('%Y-%m-%d %H:%M:%S') . "'\n                AND\n                {$diac}.inside_window = 1\n                AND\n                v.reject_if_empty = 1\n                AND\n                (diavv.value IS NULL OR diavv.value = '')\n            ";
     $message = '- Rejecting conversions with empty required variables between ' . $oStart->format('%Y-%m-%d %H:%M:%S') . ' ' . $oStart->tz->getShortName() . ' and ' . $oEnd->format('%Y-%m-%d %H:%M:%S') . ' ' . $oEnd->tz->getShortName();
     OA::debug($message, PEAR_LOG_DEBUG);
     $rows = $this->oDbh->exec($query);
     if (PEAR::isError($rows)) {
         return MAX::raiseError($rows, MAX_ERROR_DBFAILURE, PEAR_ERROR_DIE);
     }
 }
Exemple #4
0
 /**
  * A method to set the basic financial information in a summary table,
  * on the basis of given ad financial information.
  *
  * @access private
  * @param array $aAdFinanceInfo  An array of arrays, each with the ad_id, revenue and
  *                               revenue_type information for the ads that need updating.
  * @param PEAR::Date $oStartDate The start date of records that need updating.
  * @param PEAR::Date $oEndDate   The end date of records that need updating.
  * @param string $table          The name of the summary table to update with financial
  *                               information (e.g. 'data_summary_ad_hourly').
  *
  * Note: The method looks for a special variable in the service locator, called
  *       "aAdFinanceMappings". If found, and an array, the contents of the array
  *       are used to determine the column name that should be used when calculating
  *       the finance information in the SQL statement, for the appropriate revenue
  *       type. If not found, the default mapping is used:
  *       array(
  *           MAX_FINANCE_CPM => impressions,
  *           MAX_FINANCE_CPC => clicks,
  *           MAX_FINANCE_CPA => conversions
  *       )
  *
  * Note: The method looks for a special variable in the service locator, called
  *       "aAdFinanceLimitTypes". If found, and an array, the contents of the array
  *       are tested to see if the revenue type set for the ad ID to be updated is
  *       in the array. If it is not, then the finance information is not set for
  *       the ad.
  *
  * @TODO Update to deal with monthly tenancy.
  */
 function _saveSummaryUpdateAdsWithFinanceInfo($aAdFinanceInfo, $oStartDate, $oEndDate, $table)
 {
     $aConf = $GLOBALS['_MAX']['CONF'];
     if ($oStartDate->format('%H') != 0 || $oEndDate->format('%H') != 23) {
         if ($oStartDate->format('%Y-%m-%d') != $oEndDate->format('%Y-%m-%d')) {
             MAX::raiseError('_saveSummaryUpdateAdsWithFinanceInfo called with dates not on the same day.', null, PEAR_ERROR_DIE);
         }
     }
     $oServiceLocator =& OA_ServiceLocator::instance();
     // Prepare the revenue type to column name mapping array
     $aAdFinanceMappings =& $oServiceLocator->get('aAdFinanceMappings');
     if ($aAdFinanceMappings === false || !array($aAdFinanceMappings) || empty($aAdFinanceMappings)) {
         $aAdFinanceMappings = array(MAX_FINANCE_CPM => 'impressions', MAX_FINANCE_CPC => 'clicks', MAX_FINANCE_CPA => 'conversions');
     }
     // Try to get the $aAdFinanceLimitTypes array
     $aAdFinanceLimitTypes =& $oServiceLocator->get('aAdFinanceLimitTypes');
     foreach ($aAdFinanceInfo as $aInfo) {
         $query = '';
         $setInfo = true;
         // Test to see if the finance information should NOT be set for this ad
         if ($aAdFinanceLimitTypes !== false) {
             if (is_array($aAdFinanceLimitTypes) && !empty($aAdFinanceLimitTypes)) {
                 // Try to find the ad's revenue type in the array
                 if (!in_array($aInfo['revenue_type'], $aAdFinanceLimitTypes)) {
                     // It's not in the array, don't set the finance info
                     $setInfo = false;
                 }
             }
         }
         // Prepare the SQL query to set the revenue information, if required
         if ($setInfo) {
             switch ($aInfo['revenue_type']) {
                 case MAX_FINANCE_CPM:
                     $query = "\n                            UPDATE\n                                " . $this->oDbh->quoteIdentifier($aConf['table']['prefix'] . $aConf['table'][$table], true) . "\n                            SET\n                                total_revenue = {$aAdFinanceMappings[MAX_FINANCE_CPM]} * {$aInfo['revenue']} / 1000,\n                                updated = '" . OA::getNow() . "'\n                            WHERE\n                                ad_id = {$aInfo['ad_id']}\n                                AND date_time >= " . $this->oDbh->quote($oStartDate->format('%Y-%m-%d %H:%M:%S'), 'timestamp') . "\n                                AND date_time <= " . $this->oDbh->quote($oEndDate->format('%Y-%m-%d %H:%M:%S'), 'timestamp');
                     break;
                 case MAX_FINANCE_CPC:
                     $query = "\n                            UPDATE\n                                " . $this->oDbh->quoteIdentifier($aConf['table']['prefix'] . $aConf['table'][$table], true) . "\n                            SET\n                                total_revenue = {$aAdFinanceMappings[MAX_FINANCE_CPC]} * {$aInfo['revenue']},\n                                updated = '" . OA::getNow() . "'\n                            WHERE\n                                ad_id = {$aInfo['ad_id']}\n                                AND date_time >= " . $this->oDbh->quote($oStartDate->format('%Y-%m-%d %H:%M:%S'), 'timestamp') . "\n                                AND date_time <= " . $this->oDbh->quote($oEndDate->format('%Y-%m-%d %H:%M:%S'), 'timestamp');
                     break;
                 case MAX_FINANCE_CPA:
                     $query = "\n                            UPDATE\n                                " . $this->oDbh->quoteIdentifier($aConf['table']['prefix'] . $aConf['table'][$table], true) . "\n                            SET\n                                total_revenue = {$aAdFinanceMappings[MAX_FINANCE_CPA]} * {$aInfo['revenue']},\n                                updated = '" . OA::getNow() . "'\n                            WHERE\n                                ad_id = {$aInfo['ad_id']}\n                                AND date_time >= " . $this->oDbh->quote($oStartDate->format('%Y-%m-%d %H:%M:%S'), 'timestamp') . "\n                                AND date_time <= " . $this->oDbh->quote($oEndDate->format('%Y-%m-%d %H:%M:%S'), 'timestamp');
                     break;
             }
         }
         if (!empty($query)) {
             $rows = $this->oDbh->exec($query);
             if (PEAR::isError($rows)) {
                 return MAX::raiseError($rows, MAX_ERROR_DBFAILURE, PEAR_ERROR_DIE);
             }
         }
     }
 }
 /**
  * A private method to calculate the operation interval start date at the
  * upper bound of a range of operation intervals that require a ZIF update,
  * where the upper bound has been set back by the required number of
  * operation intervals so that current trends in differences between
  * forecast and actual delivery can be calculated.
  *
  * @access private
  * @param PEAR::Date $oDate The start date of the operation interval at the
  *                          upper bound of the operation interval range
  *                          requiring a ZIF update.
  * @return PEAR::Date The new upper bound date.
  */
 function _getTrendUpperDate($oDate)
 {
     $seconds = ZONE_FORECAST_TREND_OFFSET * OX_OperationInterval::secondsPerOperationInterval();
     $oDate->subtractSeconds($seconds);
     return $oDate;
 }
 /**
  * A private function to migrate raw format clicks into bucket format
  * clicks, post-upgrade to (or beyond) OpenX 2.8.
  *
  * @access private
  * @param PEAR::Date $oStart The start date of the operation interval
  *                           to migrate.
  * @param PEAR::Date $oEnd The end date of the operation interval to
  *                         migrate.
  */
 private function _migrateRawClicks($oStart, $oEnd)
 {
     $message = "   - Migrating raw clicks into the new bucket table, for the operation interval";
     OA::debug($message, PEAR_LOG_DEBUG);
     $message = "     starting " . $oStart->format('%Y-%m-%d %H:%M:%S') . ' ' . $oStart->tz->getShortName() . " and ending " . $oEnd->format('%Y-%m-%d %H:%M:%S') . ' ' . $oEnd->tz->getShortName() . ".";
     OA::debug($message, PEAR_LOG_DEBUG);
     $oServiceLocator =& OA_ServiceLocator::instance();
     $oDal =& $oServiceLocator->get('OX_Dal_Maintenance_Statistics');
     $oDal->migrateRawClicks($oStart, $oEnd);
 }
 /**
  * A method to convert the object's start and end dates into UTC format.
  */
 function toUTC()
 {
     $this->oStartDate->toUTC();
     $this->oEndDate->toUTC();
 }
Exemple #8
0
 /**
  * A method for obtaining the information required for the zone view targeting
  * statistics screen.
  *
  * @param integer $zoneId           The zone ID.
  * @param PEAR::Date $oStartDate    The start date of the operation interval.
  * @param PEAR::Date $oEndDate      The end date of the operation interval.
  *
  * @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(
  *     [$adId] => array(
  *                    ['impressions_requested'] => integer
  *                    ['priority']              => double
  *                    ['priority_factor']       => double
  *                    ['actual_impressions']    => integer
  *                )
  *        .
  *        .
  *        .
  * )
  *
  * For the operation interval specified by the start end end dates, the method
  * should return the impressions requested, priority, priority factor and
  * actual impressions delivered for each possible ad that was linked to the
  * specified zone. This requires searching the data_intermediate_ad table for
  * the ads which delivered in the zone, to get the number of acutal impressions,
  * and also searching the data_summary_ad_zone_assoc table for the ads which were
  * targeted to deliver in the zone.
  *
  * The impressions requested, priority and priority factor may need to be
  * calculated as an "averge" value, in the event that there are multiple, differing
  * values for the ad in a zone, in much the same way as is done in
  * MAX_Dal_Maintenance::getPreviousAdDeliveryInfo().
  *
  * @todo Detect and handle multiple (overlapping) intervals
  * @todo Read and return priority and priority factor
  */
 function getZoneTargetingStatistics($zone_id, &$oStartDate, &$oEndDate)
 {
     $data_table = $this->intermediate_data_table_name;
     $adzone_table_name = $this->ad_zone_table_name;
     $start_sql = $oStartDate->format("'%Y-%m-%d %H:%M:%S'");
     $end_sql = $oEndDate->format("'%Y-%m-%d %H:%M:%S'");
     $sql = "\n                SELECT\n                    interm.ad_id,\n                    impressions_requested as impressions_requested,\n                    impressions as actual_impressions,\n                    adzone.priority as priority\n                FROM\n                    {$data_table} interm,\n                    {$adzone_table_name} adzone\n                WHERE interm.zone_id = adzone.zone_id\n                    and interm.ad_id = adzone.ad_id\n                    and interm.interval_start = adzone.interval_start\n                    and interm.zone_id = " . $this->oDbh->quote($zone_id, 'integer') . "\n                    and interm.interval_start >= " . $this->oDbh->quote($start_sql, 'timestamp') . "\n                    and interm.interval_end <= " . $this->oDbh->quote($end_sql, 'timestamp') . "\n                GROUP BY ad_id\n                ";
     $results = $this->oDbh->extended->getAll($sql);
     $stats = array();
     foreach ($results as $result) {
         $ad_id = $result['ad_id'];
         $stats[$ad_id] = $result;
     }
     return $stats;
 }
 /**
  * A private method to perform assertions on the contents of the
  * log_maintenance_priority table.
  *
  * @access private
  * @param integer    $id Optional row ID to test on, if not set, tests
  *                       that table is empty.
  * @param PEAR::Date $oBeforeUpdateDate The before date to test the row with.
  * @param PEAR::Date $oAfterUpdateDate The after date to test the row with.
  * @param integer    $oi The operation interval to test the row with.
  * @param integer    $runType The run type value to test the row with.
  * @param string     $updatedTo The updated to date to test the row with, if any.
  */
 function _assertLogMaintenance($id = null, $oBeforeUpdateDate = null, $oAfterUpdateDate = null, $oi = null, $runType = null, $updatedTo = null)
 {
     $aConf = $GLOBALS['_MAX']['CONF'];
     $tableName = $aConf['table']['prefix'] . 'log_maintenance_priority';
     $table = $this->oDbh->quoteIdentifier($tableName, true);
     $query = "\n            SELECT\n                start_run,\n                end_run,\n                operation_interval,\n                run_type,\n                updated_to\n            FROM\n                {$table}";
     if (!is_null($id)) {
         $query .= "\n            WHERE\n                log_maintenance_priority_id = {$id}";
     }
     $rc = $this->oDbh->query($query);
     $aRow = $rc->fetchRow();
     if (is_null($id)) {
         // Check there are no rows returned
         $this->assertNull($aRow);
     } else {
         // Check the returned row's values
         $oStartRunDate = new Date($aRow['start_run']);
         $oEndRunDate = new Date($aRow['end_run']);
         $result = $oBeforeUpdateDate->before($oStartRunDate);
         $this->assertTrue($result);
         $result = $oBeforeUpdateDate->before($oEndRunDate);
         $this->assertTrue($result);
         $result = $oAfterUpdateDate->after($oStartRunDate);
         $this->assertTrue($result);
         $result = $oAfterUpdateDate->after($oEndRunDate);
         $this->assertTrue($result);
         $result = $oStartRunDate->after($oEndRunDate);
         $this->assertFalse($result);
         $this->assertEqual($aRow['operation_interval'], $oi);
         $this->assertEqual($aRow['run_type'], $runType);
         if (!is_null($updatedTo)) {
             $this->assertEqual($aRow['updated_to'], $updatedTo);
         } else {
             $this->assertNull($aRow['updated_to']);
         }
     }
 }