Esempio n. 1
0
 /**
  * A method to activate/deactivate campaigns, based on the date and/or the inventory
  * requirements (impressions, clicks and/or conversions). Also sends email reports
  * for any campaigns that are activated/deactivated, as well as sending email reports
  * for any campaigns that are likely to expire in the near future.
  *
  * @param Date $oDate The current date/time.
  * @return string Report on the campaigns activated/deactivated.
  */
 function manageCampaigns($oDate)
 {
     $aConf = $GLOBALS['_MAX']['CONF'];
     $oServiceLocator =& OA_ServiceLocator::instance();
     $oEmail =& $oServiceLocator->get('OA_Email');
     if ($oEmail === false) {
         $oEmail = new OA_Email();
         $oServiceLocator->register('OA_Email', $oEmail);
     }
     $report = "\n";
     // Select all campaigns in the system, where:
     //    The campaign is ACTIVE and:
     //    - The end date stored for the campaign is not null; or
     //    - The campaign has a lifetime impression, click or conversion
     //      target set.
     //
     //    That is:
     //    - It is possible for the active campaign to be automatically
     //      stopped, as it has a valid end date. (No limitations are
     //      applied to those campaigns tested, as the ME may not have
     //      run for a while, and if so, even campaigns with an end date
     //      of many, many weeks ago should be tested to ensure they are
     //      [belatedly] halted.)
     //    - It is possible for the active campaign to be automatically
     //      stopped, as it has at leaast one lifetime target that could
     //      have been reached.
     //
     //    The campaign is INACTIVE and:
     //    - The start date stored for the campaign is not null; and
     //    - The weight is greater than zero; and
     //    - The end date stored for the campaign is either null, or is
     //      greater than "today" less one day.
     //
     //    That is:
     //    - It is possible for the inactive campaign to be automatically
     //      started, as it has a valid start date. (No limitations are
     //      applied to those campaigns tested, as the ME may not have run
     //      for a while, and if so, even campaigns with an activation date
     //      of many, many weeks ago should be tested to ensure they are
     //      [belatedy] enabled.)
     //    - The campaign is not in a permanently inactive state, as a
     //      result of the weight being less then one, which means that
     //      it cannot be activated.
     //    - The test to start the campaign is unlikely to fail on account
     //      of the end date.
     $prefix = $this->getTablePrefix();
     $oNowDate = new Date($oDate);
     $oNowDate->toUTC();
     $query = "\n            SELECT\n                cl.clientid AS advertiser_id,\n                cl.account_id AS advertiser_account_id,\n                cl.agencyid AS agency_id,\n                cl.contact AS contact,\n                cl.email AS email,\n                cl.reportdeactivate AS send_activate_deactivate_email,\n                ca.campaignid AS campaign_id,\n                ca.campaignname AS campaign_name,\n                ca.views AS targetimpressions,\n                ca.clicks AS targetclicks,\n                ca.conversions AS targetconversions,\n                ca.status AS status,\n                ca.activate_time AS start,\n                ca.expire_time AS end\n            FROM\n                {$prefix}campaigns AS ca,\n                {$prefix}clients AS cl\n            WHERE\n                ca.clientid = cl.clientid\n                AND\n                ((\n                    ca.status = " . $this->oDbh->quote(OA_ENTITY_STATUS_RUNNING, 'integer') . " AND\n                    (\n                        ca.expire_time IS NOT NULL\n                        OR\n                        (\n                            ca.views > 0\n                            OR\n                            ca.clicks > 0\n                            OR\n                            ca.conversions > 0\n                        )\n                    )\n                ) OR (\n                    ca.status = " . $this->oDbh->quote(OA_ENTITY_STATUS_AWAITING, 'integer') . " AND\n                    (\n                        ca.activate_time <= " . $this->oDbh->quote($oNowDate->getDate(DATE_FORMAT_ISO), 'timestamp') . "\n                        AND\n                        (\n                            ca.weight > 0\n                            OR\n                            ca.priority > 0\n                        )\n                        AND\n                        (\n                            ca.expire_time >= " . $this->oDbh->quote($oNowDate->getDate(DATE_FORMAT_ISO), 'timestamp') . "\n                            OR\n                            ca.expire_time IS NULL\n                        )\n                    )\n                ))\n            ORDER BY\n                advertiser_id";
     OA::debug('- Requesting campaigns to test for activation/deactivation', PEAR_LOG_DEBUG);
     $rsResult = $this->oDbh->query($query);
     if (PEAR::isError($rsResult)) {
         return MAX::raiseError($rsResult, MAX_ERROR_DBFAILURE, PEAR_ERROR_DIE);
     }
     OA::debug('- Found ' . $rsResult->numRows() . ' campaigns to test for activation/deactivation', PEAR_LOG_DEBUG);
     while ($aCampaign = $rsResult->fetchRow()) {
         if ($aCampaign['status'] == OA_ENTITY_STATUS_RUNNING) {
             // The campaign is currently running, look at the campaign
             $disableReason = 0;
             $canExpireSoon = false;
             if ($aCampaign['targetimpressions'] > 0 || $aCampaign['targetclicks'] > 0 || $aCampaign['targetconversions'] > 0) {
                 OA::debug('  - Selecting impressions, clicks and conversions for this running campaign ID = ' . $aCampaign['campaign_id'], PEAR_LOG_DEBUG);
                 // The campaign has an impression, click and/or conversion target,
                 // so get the sum total statistics for the campaign
                 $query = "\n                        SELECT\n                            SUM(dia.impressions) AS impressions,\n                            SUM(dia.clicks) AS clicks,\n                            SUM(dia.conversions) AS conversions\n                        FROM\n                            " . $this->oDbh->quoteIdentifier($aConf['table']['prefix'] . $aConf['table']['data_intermediate_ad'], true) . " AS dia,\n                            " . $this->oDbh->quoteIdentifier($aConf['table']['prefix'] . $aConf['table']['banners'], true) . " AS b\n                        WHERE\n                            dia.ad_id = b.bannerid\n                            AND b.campaignid = {$aCampaign['campaign_id']}";
                 $rsResultInner = $this->oDbh->query($query);
                 $valuesRow = $rsResultInner->fetchRow();
                 if (isset($valuesRow['impressions']) || !is_null($valuesRow['clicks']) || !is_null($valuesRow['conversions'])) {
                     // There were impressions, clicks and/or conversions for this
                     // campaign, so find out if campaign targets have been passed
                     if (!isset($valuesRow['impressions'])) {
                         // No impressions
                         $valuesRow['impressions'] = 0;
                     }
                     if (!isset($valuesRow['clicks'])) {
                         // No clicks
                         $valuesRow['clicks'] = 0;
                     }
                     if (!isset($valuesRow['conversions'])) {
                         // No conversions
                         $valuesRow['conversions'] = 0;
                     }
                     if ($aCampaign['targetimpressions'] > 0) {
                         if ($aCampaign['targetimpressions'] <= $valuesRow['impressions']) {
                             // The campaign has an impressions target, and this has been
                             // passed, so update and disable the campaign
                             $disableReason |= OX_CAMPAIGN_DISABLED_IMPRESSIONS;
                         }
                     }
                     if ($aCampaign['targetclicks'] > 0) {
                         if ($aCampaign['targetclicks'] <= $valuesRow['clicks']) {
                             // The campaign has a click target, and this has been
                             // passed, so update and disable the campaign
                             $disableReason |= OX_CAMPAIGN_DISABLED_CLICKS;
                         }
                     }
                     if ($aCampaign['targetconversions'] > 0) {
                         if ($aCampaign['targetconversions'] <= $valuesRow['conversions']) {
                             // The campaign has a target limitation, and this has been
                             // passed, so update and disable the campaign
                             $disableReason |= OX_CAMPAIGN_DISABLED_CONVERSIONS;
                         }
                     }
                     if ($disableReason) {
                         // One of the campaign targets was exceeded, so disable
                         $message = '  - Exceeded a campaign quota: Deactivating campaign ID ' . "{$aCampaign['campaign_id']}: {$aCampaign['campaign_name']}";
                         OA::debug($message, PEAR_LOG_INFO);
                         $report .= $message . "\n";
                         $doCampaigns = OA_Dal::factoryDO('campaigns');
                         $doCampaigns->campaignid = $aCampaign['campaign_id'];
                         $doCampaigns->find();
                         $doCampaigns->fetch();
                         $doCampaigns->status = OA_ENTITY_STATUS_EXPIRED;
                         $result = $doCampaigns->update();
                         if ($result == false) {
                             return MAX::raiseError($rows, MAX_ERROR_DBFAILURE, PEAR_ERROR_DIE);
                         }
                         phpAds_userlogSetUser(phpAds_userMaintenance);
                         phpAds_userlogAdd(phpAds_actionDeactiveCampaign, $aCampaign['campaign_id']);
                     } else {
                         // The campaign didn't have a diable reason,
                         // it *might* possibly be diabled "soon"...
                         $canExpireSoon = true;
                     }
                 }
             }
             // Does the campaign need to be disabled due to the date?
             if (!empty($aCampaign['end'])) {
                 // The campaign has a valid end date, stored in in UTC
                 $oEndDate = new Date($aCampaign['end']);
                 $oEndDate->setTZByID('UTC');
                 if ($oDate->after($oEndDate)) {
                     // The end date has been passed; disable the campaign
                     $disableReason |= OX_CAMPAIGN_DISABLED_DATE;
                     $message = "  - Passed campaign end time of '" . $oEndDate->getDate() . " UTC" . "': Deactivating campaign ID {$aCampaign['campaign_id']}: {$aCampaign['campaign_name']}";
                     OA::debug($message, PEAR_LOG_INFO);
                     $report .= $message . "\n";
                     $doCampaigns = OA_Dal::factoryDO('campaigns');
                     $doCampaigns->campaignid = $aCampaign['campaign_id'];
                     $doCampaigns->find();
                     $doCampaigns->fetch();
                     $doCampaigns->status = OA_ENTITY_STATUS_EXPIRED;
                     $result = $doCampaigns->update();
                     if ($result == false) {
                         return MAX::raiseError($rows, MAX_ERROR_DBFAILURE, PEAR_ERROR_DIE);
                     }
                     phpAds_userlogSetUser(phpAds_userMaintenance);
                     phpAds_userlogAdd(phpAds_actionDeactiveCampaign, $aCampaign['campaign_id']);
                 } else {
                     // The campaign wasn't disabled based on the end
                     // date, to it *might* possibly be disabled "soon"...
                     $canExpireSoon = true;
                 }
             }
             if ($disableReason) {
                 // The campaign was disabled, so send the appropriate
                 // message to the campaign's contact
                 $query = "\n                        SELECT\n                            bannerid AS advertisement_id,\n                            description AS description,\n                            alt AS alt,\n                            url AS url\n                        FROM\n                            " . $this->oDbh->quoteIdentifier($aConf['table']['prefix'] . $aConf['table']['banners'], true) . "\n                        WHERE\n                            campaignid = {$aCampaign['campaign_id']}";
                 OA::debug("  - Getting the advertisements for campaign ID {$aCampaign['campaign_id']}", PEAR_LOG_DEBUG);
                 $rsResultAdvertisement = $this->oDbh->query($query);
                 if (PEAR::isError($rsResultAdvertisement)) {
                     return MAX::raiseError($rsResultAdvertisement, MAX_ERROR_DBFAILURE, PEAR_ERROR_DIE);
                 }
                 while ($advertisementRow = $rsResultAdvertisement->fetchRow()) {
                     $advertisements[$advertisementRow['advertisement_id']] = array($advertisementRow['description'], $advertisementRow['alt'], $advertisementRow['url']);
                 }
                 if ($aCampaign['send_activate_deactivate_email'] == 't') {
                     OA::debug("  - Sending campaign deactivated email ", PEAR_LOG_DEBUG);
                     $oEmail->sendCampaignActivatedDeactivatedEmail($aCampaign['campaign_id'], $disableReason);
                     // Also send campaignDeliveryEmail for the campaign we just deactivated.
                     $doClients = OA_Dal::staticGetDO('clients', $aCampaign['advertiser_id']);
                     $aAdvertiser = $doClients->toArray();
                     OA::debug("  - Sending campaign delivery email ", PEAR_LOG_DEBUG);
                     $oStart = new Date($aAdvertiser['reportlastdate']);
                     $oEnd = new Date($oDate);
                     // Set end date to tomorrow so we get stats for today.
                     $oEnd->addSpan(new Date_Span('1-0-0-0'));
                     $oEmail->sendCampaignDeliveryEmail($aAdvertiser, $oStart, $oEnd, $aCampaign['campaign_id']);
                 }
             } else {
                 if ($canExpireSoon) {
                     // The campaign has NOT been deactivated - test to see if it will
                     // be deactivated "soon", and send email(s) warning of this as required
                     OA::debug("  - Sending campaign 'soon deactivated' email ", PEAR_LOG_DEBUG);
                     $oEmail->sendCampaignImpendingExpiryEmail($oDate, $aCampaign['campaign_id']);
                 }
             }
         } elseif (!empty($aCampaign['start'])) {
             // The campaign is awaiting activation and has a valid start date, stored in UTC
             $oStartDate = new Date($aCampaign['start']);
             $oStartDate->setTZByID('UTC');
             // Find out if there are any impression, click or conversion targets for
             // the campaign (i.e. if the target values are > 0)
             $remainingImpressions = 0;
             $remainingClicks = 0;
             $remainingConversions = 0;
             if ($aCampaign['targetimpressions'] > 0 || $aCampaign['targetclicks'] > 0 || $aCampaign['targetconversions'] > 0) {
                 OA::debug("  - The campaign ID " . $aCampaign['campaign_id'] . " has an impression, click and/or conversion target, requesting impressions so far", PEAR_LOG_DEBUG);
                 $query = "\n                        SELECT\n                            SUM(dia.impressions) AS impressions,\n                            SUM(dia.clicks) AS clicks,\n                            SUM(dia.conversions) AS conversions\n                        FROM\n                            " . $this->oDbh->quoteIdentifier($aConf['table']['prefix'] . $aConf['table']['data_intermediate_ad'], true) . " AS dia,\n                            " . $this->oDbh->quoteIdentifier($aConf['table']['prefix'] . $aConf['table']['banners'], true) . " AS b\n                        WHERE\n                            dia.ad_id = b.bannerid\n                            AND b.campaignid = {$aCampaign['campaign_id']}";
                 $rsResultInner = $this->oDbh->query($query);
                 $valuesRow = $rsResultInner->fetchRow();
                 // Set the remaining impressions, clicks and conversions for the campaign
                 $remainingImpressions = $aCampaign['targetimpressions'] - $valuesRow['impressions'];
                 $remainingClicks = $aCampaign['targetclicks'] - $valuesRow['clicks'];
                 $remainingConversions = $aCampaign['targetconversions'] - $valuesRow['conversions'];
             }
             // In order for the campaign to be activated, need to test:
             // 1) That there is no impression target (<= 0), or, if there is an impression target (> 0),
             //    then there must be remaining impressions to deliver (> 0); and
             // 2) That there is no click target (<= 0), or, if there is a click target (> 0),
             //    then there must be remaining clicks to deliver (> 0); and
             // 3) That there is no conversion target (<= 0), or, if there is a conversion target (> 0),
             //    then there must be remaining conversions to deliver (> 0)
             if (($aCampaign['targetimpressions'] <= 0 || $aCampaign['targetimpressions'] > 0 && $remainingImpressions > 0) && ($aCampaign['targetclicks'] <= 0 || $aCampaign['targetclicks'] > 0 && $remainingClicks > 0) && ($aCampaign['targetconversions'] <= 0 || $aCampaign['targetconversions'] > 0 && $remainingConversions > 0)) {
                 $message = "- Passed campaign start time of '" . $oStartDate->getDate() . " UTC" . "': Activating campaign ID {$aCampaign['campaign_id']}: {$aCampaign['campaign_name']}";
                 OA::debug($message, PEAR_LOG_INFO);
                 $report .= $message . "\n";
                 $doCampaigns = OA_Dal::factoryDO('campaigns');
                 $doCampaigns->campaignid = $aCampaign['campaign_id'];
                 $doCampaigns->find();
                 $doCampaigns->fetch();
                 $doCampaigns->status = OA_ENTITY_STATUS_RUNNING;
                 $result = $doCampaigns->update();
                 if ($result == false) {
                     return MAX::raiseError($rows, MAX_ERROR_DBFAILURE, PEAR_ERROR_DIE);
                 }
                 phpAds_userlogSetUser(phpAds_userMaintenance);
                 phpAds_userlogAdd(phpAds_actionActiveCampaign, $aCampaign['campaign_id']);
                 if ($aCampaign['send_activate_deactivate_email'] == 't') {
                     OA::debug("  - Sending activation email for campaign ID " . $aCampaign['campaign_id'], PEAR_LOG_DEBUG);
                     $oEmail->sendCampaignActivatedDeactivatedEmail($aCampaign['campaign_id']);
                 }
             }
         }
     }
 }
Esempio n. 2
0
 function calc_timezone($newdate)
 {
     global $pref;
     if (!$pref['datetime'] || !$this->TimeZone) {
         $newdate = preg_replace('/UT$/', 'UTC', $newdate);
         $newdate = date("D, j M Y G:i O", strtotime($newdate));
         return $newdate;
     }
     require_once 'Date.php';
     // convert to ISO 8601 format
     if (preg_match('/(\\d+) ([a-z]+) (\\d\\d\\d?\\d?) (\\d\\d:\\d\\d:\\d\\d) ((\\+|-)\\d\\d\\d\\d|[a-z]+)/i', $newdate, $m)) {
         if (strlen($m[1]) == 1) {
             $m[1] = "0{$m['1']}";
         }
         // If a 2 digit date is given then we need to make an assumption
         // about the actual year. If year >= 80 we can safely assume that
         // it's a 20th Century date e.g. 89 becomes 1989. Otherwise lets make it
         // a 21st Century date, e.g. 08 becomes 2008
         if (strlen($m[3]) == 2) {
             $m[3] = $m[3] >= 80 ? "19{$m['3']}" : "20{$m['3']}";
         }
         // format month name with uppercase firt char e.g Sep
         $m[2] = ucfirst(strtolower($m[2]));
         // Convert Timezone ID to GMT offset
         if (!is_numeric($m[5])) {
             // convert UT > UTC
             if ($m[5] == 'UT') {
                 $m[5] = 'UTC';
             }
             $dt = new Date_TimeZone($m[5]);
             $m[5] = $dt->getRawOffset();
             if ($m[5] == 0) {
                 $m[5] = 'Z';
             } else {
                 $m[5] = $m[5] / 36000;
                 settype($m[5], 'string');
                 $m[5] = preg_replace('/(-|\\+)/', '${1}0', $m[5]);
             }
         }
         $newdate = "{$m['3']}{$this->months[$m[2]]}{$m['1']}T{$m['4']}{$m['5']}";
         // Do timezone conversion
         $date = new Date($newdate);
         $date->convertTZbyID($this->TimeZone);
         $newdate = $date->getDate();
         $newdate = date("D, j M Y G:i O", strtotime($newdate));
     } elseif (preg_match('/(\\d+) ([a-z]+) (\\d\\d\\d\\d) (\\d\\d:\\d\\d:\\d\\d) (\\w+)/i', $newdate, $m)) {
         if (strlen($m[1]) == 1) {
             $m[1] = "0{$m['1']}";
         }
         // If a 2 digit date is given then we need to make an assumption
         // about the actual year. If year >= 80 we can safely assume that
         // it's a 20th Century date e.g. 89 becomes 1989. Otherwise lets make it
         // a 21st Century date, e.g. 08 becomes 2008
         if (strlen($m[3]) == 2) {
             $m[3] = $m[3] >= 80 ? "19{$m['3']}" : "20{$m['3']}";
         }
         // format month name with uppercase firt char e.g Sep
         $m[2] = ucfirst(strtolower($m[2]));
         $newdate = "{$m['3']}{$this->months[$m[2]]}{$m['1']}";
         // Convert date from timezone ID, rather than +0900 or -1100 format, format in GMT, MST, etc
         $date = new Date($newdate);
         $date->setTZByID($m[5]);
         $newdate = $date->getDate();
         $newdate = date("D, j M Y G:i O", strtotime($newdate));
     } else {
         $newdate = date("D, j M Y G:i O", strtotime($newdate));
     }
     return $newdate;
 }
 function _convertDate($date, $tz, $end)
 {
     if (empty($date) || $date == '0000-00-00') {
         return null;
     }
     $oDate = new Date($date);
     $oDate->setTZByID($tz);
     if ($end) {
         $oDate->setHour(23);
         $oDate->setMinute(59);
         $oDate->setSecond(59);
     }
     $oDate->toUTC();
     return $oDate->getDate(DATE_FORMAT_ISO);
 }
Esempio n. 4
0
function convertTimeZone($date, $localTimeZone, $convertToTimeZone)
{
    global $timezones;
    $date = date("Y-m-d H:i:s", strtotime($date));
    $dateArray = array("year" => '', "mon" => '', "mday" => '', "hours" => '', "minutes" => '', "seconds" => '', "timezone" => '', "month" => '', "weekday" => '', "shortMon" => '');
    if ($localTimeZone == $convertToTimeZone) {
        $dateArray = getDate(strtotime($date));
        $dateArray['timezone'] = date("T", strtotime($date));
        $dateArray['shortMon'] = date("M", strtotime($date));
        if ($dateArray['mon'] < 10) {
            $dateArray['mon'] = "0" . $dateArray['mon'];
        }
        if ($dateArray['mday'] < 10) {
            $dateArray['mday'] = "0" . $dateArray['mday'];
        }
        if ($dateArray['hours'] < 10) {
            $dateArray['hours'] = "0" . $dateArray['hours'];
        }
        if ($dateArray['minutes'] < 10) {
            $dateArray['minutes'] = "0" . $dateArray['minutes'];
        }
        if ($dateArray['seconds'] < 10) {
            $dateArray['seconds'] = "0" . $dateArray['seconds'];
        }
        return $dateArray;
    }
    if (!array_key_exists($convertToTimeZone, $timezones)) {
        $dateArray = getDate(strtotime($date));
        $dateArray['timezone'] = date("T", strtotime($date));
        $dateArray['shortMon'] = date("M", strtotime($date));
        if ($dateArray['mon'] < 10) {
            $dateArray['mon'] = "0" . $dateArray['mon'];
        }
        if ($dateArray['mday'] < 10) {
            $dateArray['mday'] = "0" . $dateArray['mday'];
        }
        if ($dateArray['hours'] < 10) {
            $dateArray['hours'] = "0" . $dateArray['hours'];
        }
        if ($dateArray['minutes'] < 10) {
            $dateArray['minutes'] = "0" . $dateArray['minutes'];
        }
        if ($dateArray['seconds'] < 10) {
            $dateArray['seconds'] = "0" . $dateArray['seconds'];
        }
        return $dateArray;
    }
    $tmpDate = new Date($date);
    $tmpDate->setTZByID($localTimeZone);
    $tmpDate->convertTZByID($convertToTimeZone);
    $date = $tmpDate->format("%Y-%m-%d %H:%M:%S");
    $timezone = $tmpDate->format("%Z");
    $shortMon = $tmpDate->format("%b");
    $dateArray = getDate(strtotime($date));
    $dateArray['timezone'] = $timezone;
    $dateArray['shortMon'] = $shortMon;
    if ($dateArray['mon'] < 10) {
        $dateArray['mon'] = "0" . $dateArray['mon'];
    }
    if ($dateArray['mday'] < 10) {
        $dateArray['mday'] = "0" . $dateArray['mday'];
    }
    if ($dateArray['hours'] < 10) {
        $dateArray['hours'] = "0" . $dateArray['hours'];
    }
    if ($dateArray['minutes'] < 10) {
        $dateArray['minutes'] = "0" . $dateArray['minutes'];
    }
    if ($dateArray['seconds'] < 10) {
        $dateArray['seconds'] = "0" . $dateArray['seconds'];
    }
    return $dateArray;
}