Exemplo n.º 1
0
 /**
  * Show_Send_Step_3
  * Step 3 shows the user a report including:
  * - which split test they are sending
  * - how many subscribers it will be sent to
  * - which lists/segments they are sending to
  *
  * The user has to confirm they want to either schedule the campaign
  * or they can start sending the split test campaign
  * or (in either case), they can "cancel" the send
  * eg they chose the wrong split test to send or something
  *
  * @uses Jobs_API
  * @uses Stats_API
  * @uses Splittest_Send_API
  * @uses CheckCronEnabled
  * @uses Splittest_API::Load
  * @uses Stats_API::CheckUserStats
  * @uses Lists_API
  * @uses Segment_API
  * @uses GetApi
  */
 public function Show_Send_Step_3()
 {
     $send_details = IEM::sessionGet('SplitTestSend');
     /**
      * Check the user has been through step 1 successfully.
      */
     if (!$send_details || !isset($send_details['splitid']) || (int) $send_details['splitid'] <= 0) {
         FlashMessage(GetLang('Addon_splittest_Send_InvalidSplitTest'), SS_FLASH_MSG_ERROR, $this->admin_url);
         return;
     }
     /**
      * Make sure we're posting a proper form.
      */
     if (empty($_POST)) {
         FlashMessage(GetLang('Addon_splittest_Send_InvalidSplitTest'), SS_FLASH_MSG_ERROR, $this->admin_url);
         return;
     }
     $required_fields = array('sendfromname' => 'EnterSendFromName', 'sendfromemail' => 'EnterSendFromEmail', 'replytoemail' => 'EnterReplyToEmail');
     $erors = array();
     foreach ($required_fields as $fieldname => $lang_description) {
         if (!isset($_POST[$fieldname])) {
             $errors[] = GetLang('Addon_splittest_Send_Step3_' . $lang_description);
             continue;
         }
         $posted_value = trim($_POST[$fieldname]);
         if ($posted_value == '') {
             $errors[] = GetLang('Addon_splittest_Send_Step3_' . $lang_description);
             continue;
         }
     }
     if (!empty($errors)) {
         $errormsg = implode('<br/>', $errors);
         FlashMessage(sprintf(GetLang('Addon_splittest_Send_Step3_FieldsMissing'), $errormsg), SS_FLASH_MSG_ERROR, $this->admin_url . '&Action=Send&Step=2');
         return;
     }
     require_once SENDSTUDIO_API_DIRECTORY . '/jobs.php';
     $jobapi = new Jobs_API();
     require_once SENDSTUDIO_API_DIRECTORY . '/stats.php';
     $statsapi = new Stats_API();
     $send_api = $this->GetApi('Splittest_Send');
     $send_details['SendFromName'] = $_POST['sendfromname'];
     $send_details['SendFromEmail'] = $_POST['sendfromemail'];
     $send_details['ReplyToEmail'] = $_POST['replytoemail'];
     /**
      * If the user has access to set bounce details, this will be available.
      * If they don't, we'll use the email from the settings page.
      */
     if (isset($_POST['bounceemail'])) {
         $send_details['BounceEmail'] = $_POST['bounceemail'];
     } else {
         $send_details['BounceEmail'] = SENDSTUDIO_BOUNCE_ADDRESS;
     }
     /**
      * Set the charset.
      */
     $send_details['Charset'] = SENDSTUDIO_CHARSET;
     $to_firstname = false;
     if (isset($_POST['to_firstname']) && (int) $_POST['to_firstname'] > 0) {
         $to_firstname = (int) $_POST['to_firstname'];
     }
     $send_details['To_FirstName'] = $to_firstname;
     $to_lastname = false;
     if (isset($_POST['to_lastname']) && (int) $_POST['to_lastname'] > 0) {
         $to_lastname = (int) $_POST['to_lastname'];
     }
     $send_details['To_LastName'] = $to_lastname;
     $send_details['SendStartTime'] = $send_api->GetServerTime();
     foreach (array('success', 'total', 'failure') as $area) {
         $send_details['EmailResults'][$area] = 0;
     }
     $send_details['NotifyOwner'] = 1;
     /**
      * Split campaigns have to track opens & link clicks
      * There's no other way they will work.
      */
     $send_details['TrackOpens'] = $send_details['TrackLinks'] = 1;
     $send_details['Multipart'] = 0;
     if (isset($_POST['multipart'])) {
         $send_details['Multipart'] = 1;
     }
     $send_details['EmbedImages'] = 0;
     if (isset($_POST['embedimages'])) {
         $send_details['EmbedImages'] = 1;
     }
     /**
      * If cron is enabled, we'll get new info we need to take into account.
      */
     if (self::CheckCronEnabled()) {
         /**
          * The default (from above) is to "notify", so if it's not set, don't notify.
          */
         if (!isset($_POST['notifyowner'])) {
             $send_details['NotifyOwner'] = 0;
         }
         /**
          * If we're not sending immediately, then check the date/time.
          * We don't allow sending in past dates.
          */
         if (!isset($_POST['sendimmediately'])) {
             $hrs = $_POST['sendtime_hours'];
             $am_pm = null;
             if (isset($_POST['sendtime_ampm'])) {
                 $am_pm = strtolower($_POST['sendtime_ampm']);
             }
             if ($am_pm == 'pm' && $hrs < 12) {
                 $hrs += 12;
             }
             if ($am_pm == 'am' && $hrs == 12) {
                 $hrs = 0;
             }
             $gmt_check_time = AdjustTime(array($hrs, $_POST['sendtime_minutes'], 0, $_POST['datetime']['month'], $_POST['datetime']['day'], $_POST['datetime']['year']), true);
             $now = $send_api->GetServerTime();
             /**
              * There's a leeway of 5 minutes just in case there are any server/time issues.
              */
             $leeway = 5 * 60;
             if ($gmt_check_time < $now - $leeway) {
                 FlashMessage(GetLang('Addon_splittest_Send_Step2_SendingInPast'), SS_FLASH_MSG_ERROR, $this->admin_url . '&Action=Send&Step=2');
                 return;
             }
             $send_details['SendStartTime'] = $gmt_check_time;
         }
     }
     $this->template_system->Assign('AdminUrl', $this->admin_url, false);
     $api = $this->GetApi();
     $split_campaign_details = $api->Load($send_details['splitid']);
     $sendingCampaigns = array();
     $send_details['newsletters'] = array();
     foreach ($split_campaign_details['splittest_campaigns'] as $campaignid => $campaignname) {
         $sendingCampaigns[$campaignid] = htmlspecialchars($campaignname, ENT_QUOTES, SENDSTUDIO_CHARSET);
         $send_details['newsletters'][$campaignid] = $campaignid;
     }
     /**
      * Before saving the job details, randomize the newsletter order.
      * This is so we don't send the newsletters in the same order every time.
      */
     shuffle($send_details['newsletters']);
     $send_list = array();
     switch ($send_details['sendingto']['sendtype']) {
         case 'list':
             require_once SENDSTUDIO_API_DIRECTORY . '/lists.php';
             $list_api = new Lists_API();
             foreach ($send_details['sendingto']['sendids'] as $listid) {
                 $list_api->Load($listid);
                 $send_list[] = htmlspecialchars($list_api->Get('name'), ENT_QUOTES, SENDSTUDIO_CHARSET);
             }
             $this->template_system->Assign('SendingToLists', true);
             break;
         case 'segment':
             require_once SENDSTUDIO_API_DIRECTORY . '/segment.php';
             $segment_api = new Segment_API();
             foreach ($send_details['sendingto']['sendids'] as $segmentid) {
                 $segment_api->Load($segmentid);
                 $send_list[] = htmlspecialchars($segment_api->Get('segmentname'), ENT_QUOTES, SENDSTUDIO_CHARSET);
             }
             // The job expects a 'Segments' element, otherwise it will send to entire lists.
             $send_details['Segments'] = $send_details['sendingto']['sendids'];
             $this->template_system->Assign('SendingToSegments', true);
             break;
     }
     $subscriber_count = $send_details['sendsize'];
     $user = IEM::userGetCurrent();
     if ($user->HasAccess('Newsletters')) {
         $this->template_system->Assign('ApplicationUrl', $this->application_url, false);
         $this->template_system->Assign('NewsletterView', true);
     }
     $send_criteria = array();
     // can only send to active subscribers.
     $send_criteria['Status'] = 'a';
     $send_criteria['List'] = $send_details['sendingto']['Lists'];
     $send_details['SendCriteria'] = $send_criteria;
     $check_stats = $statsapi->CheckUserStats($user, $subscriber_count, $send_details['SendStartTime']);
     list($ok_to_send, $not_ok_to_send_reason) = $check_stats;
     if (!$ok_to_send) {
         require_once SENDSTUDIO_LANGUAGE_DIRECTORY . '/default/send.php';
         FlashMessage(GetLang($not_ok_to_send_reason), SS_FLASH_MSG_ERROR, $this->admin_url . '&Action=Send&Step=2');
         return;
     }
     /**
      * The 'job' expects a 'Lists' element, so just point it to the sendingto lists.
      */
     $send_details['Lists'] = $send_details['sendingto']['Lists'];
     $send_details['SendSize'] = $subscriber_count;
     $jobcreated = $jobapi->Create('splittest', $send_details['SendStartTime'], $user->userid, $send_details, 'splittest', $send_details['splitid'], $send_details['sendingto']['Lists']);
     $send_details['Job'] = $jobcreated;
     IEM::sessionSet('JobSendSize', $subscriber_count);
     // if we're not using scheduled sending, create the queue and start 'er up!
     if (!self::CheckCronEnabled()) {
         require_once SENDSTUDIO_API_DIRECTORY . '/subscribers.php';
         $subscriberApi = new Subscribers_API();
         $sendqueue = $subscriberApi->CreateQueue('splittest');
         $jobapi->StartJob($jobcreated);
         $queuedok = $jobapi->JobQueue($jobcreated, $sendqueue);
         $queueinfo = array('queueid' => $sendqueue, 'queuetype' => 'splittest', 'ownerid' => $user->userid);
         if ($send_details['sendingto']['sendtype'] == 'segment') {
             $subscriberApi->GetSubscribersFromSegment($send_details['sendingto']['sendids'], false, $queueinfo, 'nosort');
         } else {
             $subscriberApi->GetSubscribers($send_criteria, array(), false, $queueinfo, $user->userid);
         }
         if (SENDSTUDIO_DATABASE_TYPE == 'pgsql') {
             $subscriberApi->Db->OptimizeTable(SENDSTUDIO_TABLEPREFIX . "queues");
         }
         $subscriberApi->RemoveDuplicatesInQueue($sendqueue, 'splittest', $send_details['sendingto']['Lists']);
         $subscriberApi->RemoveBannedEmails($send_details['sendingto']['Lists'], $sendqueue, 'splittest');
         $subscriberApi->RemoveUnsubscribedEmails($send_details['sendingto']['Lists'], $sendqueue, 'splittest');
         if (SENDSTUDIO_DATABASE_TYPE == 'pgsql') {
             $subscriberApi->Db->OptimizeTable(SENDSTUDIO_TABLEPREFIX . "queues");
         }
         $send_details['SendSize'] = $subscriberApi->QueueSize($sendqueue, 'splittest');
         $send_details['Stats'] = array();
         $statids = array();
         foreach ($send_details['newsletters'] as $newsletterid) {
             $newsletterstats = $send_details;
             $newsletterstats['Job'] = $jobcreated;
             $newsletterstats['Queue'] = $sendqueue;
             $newsletterstats['SentBy'] = $queueinfo['ownerid'];
             $newsletterstats['SendType'] = 'splittest';
             $newsletterstats['Newsletter'] = $newsletterid;
             $newsletterstats['Lists'] = $send_details['sendingto']['Lists'];
             $newsletterstats['SendCriteria'] = $send_criteria;
             $statid = $statsapi->SaveNewsletterStats($newsletterstats);
             $statids[] = $statid;
             $send_details['Stats'][$newsletterid] = $statid;
             $statsapi->RecordUserStats($user->userid, $jobcreated, $subscriber_count, $send_details['SendStartTime'], $statid);
         }
         $send_api->SaveSplitStats($send_details['splitid'], $jobcreated, $statids);
         $jobapi->PauseJob($jobcreated);
     }
     $this->template_system->Assign('sendingCampaigns', $sendingCampaigns);
     $this->template_system->Assign('sendLists', $send_list);
     $send_size = $send_details['SendSize'];
     IEM::sessionSet('SplitTestSendDetails', $send_details);
     /**
      * This is used to work out if we should automatically clean up a half-finished send process.
      * We need to do this because a half-finished send may have taken email-credits from a user
      * so we need to give them back.
      */
     IEM::sessionSet('SplitTestSend_Cleanup', $send_details);
     if ($send_size == 1) {
         $send_size_msg = GetLang('Addon_splittest_Send_Step3_Size_One');
     } else {
         $send_size_msg = sprintf(GetLang('Addon_splittest_Send_Step3_Size_Many'), $this->PrintNumber($send_size));
     }
     $this->template_system->Assign('SendingToNumberOfContacts', $send_size_msg);
     $this->template_system->Assign('CronEnabled', false);
     if (self::CheckCronEnabled()) {
         /**
          * If cron is enabled, then record the stats allocation now.
          * This will get fixed up when the actual send starts as it needs to create a stat item for each newsletter.
          * However, at this stage we just need to record that the user is doing a send so it's removed from their send-allocation.
          */
         $statsapi->RecordUserStats($user->userid, $jobcreated, $subscriber_count, $send_details['SendStartTime']);
         $user_adjusted_time = AdjustTime($send_details['SendStartTime'], false, GetLang('TimeFormat'), true);
         $this->template_system->Assign('CronEnabled', true);
         $this->template_system->Assign('JobScheduleTime', sprintf(GetLang('Addon_splittest_Send_Step3_JobScheduleTime'), $user_adjusted_time));
         /**
          * Mark the job as "waiting".
          * This will be used on the "manage" page to show it's waiting to send out.
          */
         $send_api->StartJob($jobcreated, $send_details['splitid'], 'w');
     }
     $this->template_system->ParseTemplate('send_step3');
 }
 /**
  * replaceTagContent
  * This is used to replace the place holder for the email to the correct content
  *
  * @param EventData_IEM_ADDON_DYNAMICCONTENTTAGS_REPLACETAGCONTENT $data This will be set and used by the caller function
  * @return void This will return the variable via $data instead of return via function
  */
 public static function replaceTagContent(EventData_IEM_ADDON_DYNAMICCONTENTTAGS_REPLACETAGCONTENT $data)
 {
     require_once SENDSTUDIO_API_DIRECTORY . '/subscribers.php';
     $subsrciberApi = new Subscribers_API();
     $subscriberInfo = $data->info;
     //if there's no data then there's no point in finishing
     if (empty($subscriberInfo) || empty($subscriberInfo[0])) {
         return;
     }
     foreach ($subscriberInfo as $subscriberInfoEntry) {
         if (empty($subscriberInfoEntry) || empty($subscriberInfoEntry['emailaddress']) || empty($subscriberInfoEntry['subscriberid'])) {
             continue;
         }
         $tagObject = new Addons_dynamiccontenttags();
         $subscriberList = $subsrciberApi->GetAllListsForEmailAddress($subscriberInfoEntry['emailaddress'], $data->lists);
         if (is_array($subscriberList)) {
             foreach ($subscriberList as $listKey => $listVal) {
                 $subscriberList[$listKey] = $listVal['listid'];
             }
         } else {
             $subscriberList = array($subscriberList);
         }
         // preload the array key value and customfield id
         $preloadCustomFieldLoc = array();
         if (is_array($subscriberInfoEntry['CustomFields'])) {
             foreach ($subscriberInfoEntry['CustomFields'] as $customFieldKey => $customFieldVal) {
                 $preloadCustomFieldLoc[$customFieldVal['fieldid']] = $customFieldKey;
             }
         }
         $tagObject->loadTagsByList($subscriberList);
         if ($tagObject->getTagObjectsSize()) {
             $tagsTobeReplaced = array();
             $tagsContentTobeReplaced = array();
             $permanentRulesMatches = array('email' => 'emailaddress', 'format' => 'format', 'confirmation' => 'confirmed', 'subscribe' => 'subscribedate');
             $generatedContent = '';
             //stores the content blocks that will be used in this tag, initializing for scope
             foreach ($tagObject->tags as $tagEntry) {
                 $tagEntry->loadBlocks();
                 $blocks = $tagEntry->getBlocks();
                 $defaultBlock = null;
                 $anyRulesPassed = false;
                 foreach ($blocks as $blockEntry) {
                     $rulesPassed = true;
                     $decodedRules = $blockEntry->getDecodedRules();
                     foreach ($decodedRules->Rules[0]->rules as $ruleEntry) {
                         $continue = false;
                         $tempRuleValues = trim(strtolower($ruleEntry->rules->ruleValues));
                         $tempActualValues = isset($permanentRulesMatches[$ruleEntry->rules->ruleName]) && isset($subscriberInfoEntry[$permanentRulesMatches[$ruleEntry->rules->ruleName]]) ? trim(strtolower($subscriberInfoEntry[$permanentRulesMatches[$ruleEntry->rules->ruleName]])) : '';
                         switch ($ruleEntry->rules->ruleName) {
                             case 'email':
                             case 'format':
                             case 'confirmation':
                                 $continue = true;
                                 break;
                             case 'status':
                                 $tempActualValues = array();
                                 $tempIndex = '';
                                 switch ($tempRuleValues) {
                                     case 'a':
                                         $tempIndex = 'notboth';
                                         break;
                                     case 'b':
                                         $tempIndex = 'bounced';
                                         break;
                                     case 'u':
                                         $tempIndex = 'unsubscribed';
                                         break;
                                 }
                                 switch ($ruleEntry->rules->ruleOperator) {
                                     case 'equalto':
                                         if (isset($subscriberInfoEntry[$tempIndex]) && $subscriberInfoEntry[$tempIndex] == 0) {
                                             $rulesPassed = false;
                                         } elseif (!isset($subscriberInfoEntry[$tempIndex]) && !($subscriberInfoEntry['bounced'] == 0 && $subscriberInfoEntry['unsubscribed'] == 0)) {
                                             $rulesPassed = false;
                                         }
                                         break;
                                     case 'notequalto':
                                         if (isset($subscriberInfoEntry[$tempIndex]) && !($subscriberInfoEntry[$tempIndex] == 0)) {
                                             $rulesPassed = false;
                                         } elseif (!isset($subscriberInfoEntry[$tempIndex]) && ($subscriberInfoEntry['bounced'] == 0 && $subscriberInfoEntry['unsubscribed'] == 0)) {
                                             $rulesPassed = false;
                                         }
                                         break;
                                 }
                                 break;
                             case 'subscribe':
                                 // date conversion
                                 $tempActualValues = strtotime(date('Y-m-d', $tempActualValues));
                                 $tempRuleValues = explode('/', $tempRuleValues);
                                 $tempRuleValues = strtotime(implode('-', array_reverse($tempRuleValues)));
                                 $continue = true;
                                 break;
                             case 'campaign':
                                 switch ($ruleEntry->rules->ruleOperator) {
                                     case 'equalto':
                                         if (!$subsrciberApi->IsSubscriberHasOpenedNewsletters($subscriberInfoEntry['emailaddress'], $tempRuleValues)) {
                                             $rulesPassed = false;
                                         }
                                         break;
                                     case 'notequalto':
                                         if ($subsrciberApi->IsSubscriberHasOpenedNewsletters($subscriberInfoEntry['emailaddress'], $tempRuleValues)) {
                                             $rulesPassed = false;
                                         }
                                         break;
                                 }
                                 break;
                             default:
                                 $continue = true;
                         }
                         if ($continue) {
                             if ((int) $ruleEntry->rules->ruleName) {
                                 $tempActualValues = isset($preloadCustomFieldLoc[$ruleEntry->rules->ruleName]) && isset($subscriberInfoEntry['CustomFields'][$preloadCustomFieldLoc[$ruleEntry->rules->ruleName]]['data']) ? trim(strtolower($subscriberInfoEntry['CustomFields'][$preloadCustomFieldLoc[$ruleEntry->rules->ruleName]]['data'])) : '';
                                 if ($ruleEntry->rules->ruleType == 'date') {
                                     $tempActualValues = split('/', $tempActualValues);
                                     $tempActualValues = strtotime(implode('-', array_reverse($tempActualValues)));
                                     $tempRuleValues = split('/', $tempRuleValues);
                                     $tempRuleValues = strtotime(implode('-', array_reverse($tempRuleValues)));
                                 }
                             }
                             switch ($ruleEntry->rules->ruleType) {
                                 case 'text':
                                 case 'textarea':
                                 case 'dropdown':
                                 case 'number':
                                 case 'radiobutton':
                                 case 'date':
                                     switch ($ruleEntry->rules->ruleOperator) {
                                         case 'equalto':
                                             if (!($tempActualValues == $tempRuleValues)) {
                                                 $rulesPassed = false;
                                             }
                                             break;
                                         case 'notequalto':
                                             if ($tempActualValues == $tempRuleValues) {
                                                 $rulesPassed = false;
                                             }
                                             break;
                                         case 'like':
                                             if (!strstr($tempActualValues, $tempRuleValues)) {
                                                 $rulesPassed = false;
                                             }
                                             break;
                                         case 'notlike':
                                             if (strstr($tempActualValues, $tempRuleValues)) {
                                                 $rulesPassed = false;
                                             }
                                             break;
                                         case 'greaterthan':
                                             if ($tempActualValues <= $tempRuleValues) {
                                                 $rulesPassed = false;
                                             }
                                             break;
                                         case 'lessthan':
                                             if ($tempActualValues >= $tempRuleValues) {
                                                 $rulesPassed = false;
                                             }
                                             break;
                                         default:
                                             $rulesPassed = false;
                                     }
                                     break;
                                 case 'checkbox':
                                     $tempActualValues = unserialize($tempActualValues);
                                     $tempRuleValues = explode(', ', $tempRuleValues);
                                     $tempRuleValues = is_array($tempRuleValues) ? $tempRuleValues : array();
                                     $tempActualValues = is_array($tempActualValues) ? $tempActualValues : array();
                                     switch ($ruleEntry->rules->ruleOperator) {
                                         case 'equalto':
                                             if (sizeof(array_intersect($tempActualValues, $tempRuleValues)) != sizeof($tempRuleValues)) {
                                                 $rulesPassed = false;
                                             }
                                             break;
                                         case 'notequalto':
                                             if (sizeof(array_intersect($tempActualValues, $tempRuleValues)) == sizeof($tempRuleValues)) {
                                                 $rulesPassed = false;
                                             }
                                             break;
                                         default:
                                             $rulesPassed = false;
                                     }
                                     break;
                                 default:
                                     $rulesPassed = false;
                             }
                         }
                     }
                     if ($blockEntry->isActivated()) {
                         $defaultBlock = $decodedRules;
                     }
                     if ($rulesPassed && !$blockEntry->isActivated()) {
                         $generatedContent = empty($generatedContent) ? '' : "{$generatedContent}<br />\r\n";
                         $generatedContent .= $decodedRules->Content;
                         $anyRulesPassed = true;
                     }
                 }
                 $data->contentTobeReplaced[$subscriberInfoEntry['subscriberid']]['tagsTobeReplaced'][] = '%%[' . trim($tagEntry->getName()) . ']%%';
                 if ($anyRulesPassed) {
                     $data->contentTobeReplaced[$subscriberInfoEntry['subscriberid']]['tagsContentTobeReplaced'][] = $generatedContent;
                 } else {
                     $data->contentTobeReplaced[$subscriberInfoEntry['subscriberid']]['tagsContentTobeReplaced'][] = $defaultBlock->Content;
                 }
                 $generatedContent = '';
             }
         }
     }
 }
Exemplo n.º 3
0
	/**
	 * _PopulateQueryCache
	 * Process and populate query cache. It gets called whenever a record is saved (ie. created or edited).
	 *
	 * @return Boolean Returns TRUE if successful, FALSE otherwise
	 *
	 * @uses Segment_API::$searchinfo
	 * @uses Subscriber_API
	 * @uses Subscriber_API::GenerateQueryFromSegmentRules()
	 *
	 * @access private
	 */
	function _PopulateQueryCache()
	{
		if (!class_exists('Subscribers_API', false)) {
			require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'subscribers.php');
		}

		$subscriberAPI = new Subscribers_API();
		$status = $subscriberAPI->GenerateQueryFromSegmentRules($this->searchinfo['Lists'], $this->searchinfo['Rules']);
		if ($status === false) {
			trigger_error('"Rules" cannot be processed', E_USER_WARNING);
			return false;
		}

		$this->searchinfo['_cache'] = array(
			'selectQuery' => $status['selectQuery'],
			'countQuery' => $status['countQuery']
		);

		return true;
	}
	/**
	 * _getCustomFieldValueForSubscriber
	 *
	 * This function is copied from Jobs_Autoresponder::SetupCustomFields.
	 * The function will fetch custom field values for specified subscribers
	 *
	 * @param Int $listid The list the subscribers are on. Passed to the GetAllSubscriberCustomFields method to restrict the search/loading.
	 * @param Array $custom_fields_to_replace The custom field id's to load/replace
	 * @param Array $recipients The recipients to load the custom fields for.
	 *
	 * @see Jobs_Send::SetupCustomFields
	 * @see Jobs_Autoresponders::SetupCustomFields
	 * @uses Subscriber_API::GetAllSubscriberCustomFields
	 *
	 * @return Array Returns a multidimensional array containing all subscribers and all of their custom field values.
	 */
	private function _getCustomFieldValueForSubscriber($listid, $custom_fields_to_replace, $recipients)
	{
		static $subscribersAPI = null;

		if (is_null($subscribersAPI)) {
			require_once (dirname(__FILE__) . '/subscribers.php');
			$subscribersAPI = new Subscribers_API();
		}

		$all_customfields = $subscribersAPI->GetAllSubscriberCustomFields($listid, $custom_fields_to_replace, $recipients);

		// rather than using the customfield api to do all of this (which would require loading each item separately, then running GetRealValue) we'll do the "dodgy" and do it all here instead.

		foreach ($all_customfields as $subscriberid => $customfield_list) {
			$fields_found = array();
			foreach ($customfield_list as $p => $details) {

				$fields_found[] = $details['fieldname'];
				if ($details['data'] === null || $details['data'] == '') {
					continue;
				}

				$fieldid = $details['fieldid'];

				switch ($details['fieldtype']) {
					case 'date':
						list($dd, $mm, $yy) = explode('/', $details['data']);
						$real_order = array();
						$settings = unserialize($details['fieldsettings']);
						$field_order = array_slice($settings['Key'], 0, 3);
						foreach ($field_order as $posp => $order) {
							switch ($order) {
								case 'day':
									$real_order[] = $dd;
								break;
								case 'month':
									$real_order[] = $mm;
								break;
								case 'year':
									$real_order[] = $yy;
								break;
							}
						}
						$all_customfields[$subscriberid][$p]['data'] = implode('/', $real_order);
					break;

					case 'dropdown':
						$settings = unserialize($details['fieldsettings']);
						$data = $details['data'];
						$pos = array_search($data, $settings['Key']);
						if (is_numeric($pos)) {
							$all_customfields[$subscriberid][$p]['data'] = $settings['Value'][$pos];
						}
					break;

					case 'radiobutton':
						$settings = unserialize($details['fieldsettings']);
						$data = $details['data'];
						$pos = array_search($data, $settings['Key']);

						if (is_numeric($pos)) {
							$all_customfields[$subscriberid][$p]['data'] = $settings['Value'][$pos];
						}
					break;

					case 'checkbox':
						$settings = unserialize($details['fieldsettings']);
						$data = $details['data'];

						$value = unserialize($data);

						$return_value = array();

						foreach ($settings['Key'] as $pos => $key) {
							if (in_array($key, $value)) {
								$return_value[] = $settings['Value'][$pos];
							}
						}

						$data = implode(',', $return_value);

						$all_customfields[$subscriberid][$p]['data'] = $data;
					break;
				}
			}

			if (!isset($all_customfields[$subscriberid])) {
				$all_customfields[$subscriberid] = array();
			}

			/**
			* If the subscriber only has some custom fields from the database, make sure we fill in the rest with blank entries.
			* Otherwise in some cases they could end up with custom fields not being replaced.
			* Eg if they have one custom field entry, then they skip the check around line 385.
			*
			* Makes for double handling of the custom fields but this should ensure you don't get half-managed custom fields.
			*/
			foreach ($custom_fields_to_replace as $fieldid => $fieldname) {
				if (!in_array($fieldname, $fields_found)) {
					$all_customfields[$subscriberid][] = array (
						'fieldid' => $fieldid,
						'fieldname' => $fieldname,
						'fieldtype' => 'text',
						'defaultvalue' => '',
						'fieldsettings' => '',
						'subscriberid' => $subscriberid,
						'data' => ''
					);
				}
			}
		}

		return $all_customfields;
	}
Exemplo n.º 5
0
 /**
  * OpenTracked
  * Logs an event when a user opens a campaign or autoresponder
  *
  * @uses Subscriber_API::AddEvent
  * @uses Stats_API::GetNewsletterSummary
  * @uses Stats_API::GetAutoresponderSummary
  *
  * @return Void Returns nothing
  */
 public static function OpenTracked($eventdata)
 {
     if (!self::LoadSelf()) {
         return;
     }
     $subscribersapi = new Subscribers_API();
     $statsapi = new Stats_API();
     if (!isset($eventdata->open_details['subscriberid']) || !isset($eventdata->open_details['listid'])) {
         return;
     }
     switch ($eventdata->statstype[0]) {
         case 'n':
             $newsletter = $statsapi->GetNewsletterSummary($eventdata->open_details['statid'], true);
             if (empty($newsletter) || !isset($newsletter['newsletterid'])) {
                 return false;
             }
             $event = array('type' => GetLang('Addon_emaileventlog_open'), 'eventdate' => $subscribersapi->GetServerTime(), 'subject' => sprintf(GetLang('Addon_emaileventlog_open_subject'), htmlspecialchars($newsletter['newslettername'], ENT_QUOTES, SENDSTUDIO_CHARSET)), 'notes' => GetLang('Addon_emaileventlog_opened_campaign'));
             break;
         case 'a':
             $stats = $statsapi->FetchStats($eventdata->open_details['statid'], 'a');
             $autoresponder = $statsapi->GetAutoresponderSummary($stats['autoresponderid'], true);
             if (empty($autoresponder) || !isset($autoresponder['autoresponderid'])) {
                 return false;
             }
             $event = array('type' => GetLang('Addon_emaileventlog_open_autoresponder'), 'eventdate' => $subscribersapi->GetServerTime(), 'subject' => sprintf(GetLang('Addon_emaileventlog_open_autoresponder_subject'), htmlspecialchars($autoresponder['autorespondername'], ENT_QUOTES, SENDSTUDIO_CHARSET)), 'notes' => GetLang('Addon_emaileventlog_opened_autoresponder'));
             break;
         default:
     }
     $subscribersapi->AddEvent($eventdata->open_details['subscriberid'], $eventdata->open_details['listid'], $event);
 }
Exemplo n.º 6
0
	/**
	 * _getSubscriberIDSFromList
	 * Get all subsriber IDs with the same email address within a list
	 *
	 * @param Integer $subscriberid Subscriber ID
	 * @param Array $lists An array of list IDs
	 *
	 * @return Array|FALSE an array of return records that can be used to pass through Api::AddToQueue(), FALSE otherwise
	 */
	private function _getSubscriberIDSFromList($subscriberid, $lists)
	{
		if (!is_array($lists) || empty($lists)) {
			return array(array('subscriberid' => $subscriberid));
		}

		require_once(dirname(__FILE__) . '/subscribers.php');
		$subscribersapi = new Subscribers_API();

		$emailaddress = $subscribersapi->GetEmailForSubscriber($subscriberid);
		if (!$emailaddress) {
			return array(array('subscriberid' => $subscriberid));
		}

		$records = $subscribersapi->GetAllListsForEmailAddress($emailaddress, $lists);

		if (empty($records)) {
			return array(array('subscriberid' => $subscriberid));
		}

		return $records;
	}
Exemplo n.º 7
0
 /**
  * _ProcessJob
  * This method does the "setup work" for a split test campaign.
  *
  * If a job is passed in that hasn't been started before, it will set everything up:
  * - create a "queue" of recipients
  * - clean the queue (remove banned/duplicate recipients etc)
  * - set up stats for each newsletter in the split test campaign
  * - save stats for the user sending the campaign to take off credits etc
  *
  * If a job is passed in that has been set up before, it just loads the data up.
  *
  * Once it has done either of those, it gives the details to the Splittest_Send_API class
  * and then calls _ActionJob.
  * Based on what that returns, it will either mark the job as complete or not.
  *
  * If the job is a percentage split test send (send to first X % of a list/segment), then
  * it sets the appropriate flags etc to make sure we only send to that first X%.
  * If the job hasn't been set up before, it works out the limit and sets the details in the jobdetails
  * which are then saved in the database in case the job dies or is paused etc.
  *
  * If the job is a percentage split test send and it's time to send to the rest of the list/segment,
  * then it works out the "best" one to send and sets the appropriate variables for that to happen.
  *
  * @param Int $jobid The specific job id we're going to process.
  *
  * @uses _jobid
  * @uses StartJob
  * @uses PauseJob
  * @uses LoadJob
  * @uses GetUser
  * @uses GetJobQueue
  * @uses CreateQueue
  * @uses JobQueue
  * @uses GetSubscribersFromSegment
  * @uses GetSubscribers
  * @uses RemoveDuplicatesInQueue
  * @uses RemoveBannedEmails
  * @uses RemoveUnsubscribedEmails
  * @uses QueueSize
  * @uses _CalculateBestNewsletter
  * @uses _FinishJob
  * @uses _ActionJob
  * @uses _CalculateBestNewsletter
  *
  * @return Boolean Returns whether the job was processed or not. If a job could not be processed, it returns false. Otherwise it returns true.
  */
 private function _ProcessJob($jobid = 0)
 {
     if ($jobid <= 0) {
         return false;
     }
     $this->_jobid = $jobid;
     /**
      * Load the job, then start it.
      * We need to do this so when we call "StartJob" we can give it the splitid to "start" as well.
      */
     $jobinfo = $this->LoadJob($jobid);
     $jobdetails = $jobinfo['jobdetails'];
     /**
      * Need to load the split campaign
      * before starting the job
      * so if we're in "t"imeout mode,
      * we can look at the stats
      * We also need the weighting's from the split campaign
      * to work it out.
      */
     $this->splitcampaign_details = $this->_splittest_api->Load($jobdetails['splitid']);
     /**
      * If it's a "t"imeout, work out the best stat.
      */
     if ($jobinfo['jobstatus'] == 't') {
         $jobdetails['newsletters'] = $this->_CalculateBestNewsletter($jobdetails['Stats']);
         /**
          * Also need to kill off the "percentage_send_maximum" element
          * as this would cause the job to go into "timeout" mode again.
          */
         unset($jobdetails['percentage_send_maximum']);
     }
     if (!$this->StartJob($jobid, $jobdetails['splitid'])) {
         $this->PauseJob($jobid);
         return false;
     }
     // ----- "Login" to the system as the job's owner.
     $user = GetUser($jobinfo['ownerid']);
     IEM::userLogin($jobinfo['ownerid'], false);
     // -----
     $queueid = false;
     // if there's no queue, start one up.
     if (!($queueid = $this->GetJobQueue($jobid))) {
         /**
          * Randomize the newsletters
          * It's probably already been done but can't hurt to do it again.
          */
         shuffle($jobdetails['newsletters']);
         $sendqueue = $this->CreateQueue('splittest');
         $queueok = $this->JobQueue($jobid, $sendqueue);
         $send_criteria = $jobdetails['SendCriteria'];
         $queueinfo = array('queueid' => $sendqueue, 'queuetype' => 'splittest', 'ownerid' => $jobinfo['ownerid']);
         if (isset($jobdetails['Segments']) && is_array($jobdetails['Segments'])) {
             $this->_subscribers_api->GetSubscribersFromSegment($jobdetails['Segments'], false, $queueinfo, 'nosort');
         } else {
             $this->_subscribers_api->GetSubscribers($send_criteria, array(), false, $queueinfo, $sendqueue);
         }
         if (SENDSTUDIO_DATABASE_TYPE == 'pgsql') {
             $this->Db->OptimizeTable(SENDSTUDIO_TABLEPREFIX . "queues");
         }
         $this->_subscribers_api->RemoveDuplicatesInQueue($sendqueue, 'splittest', $jobdetails['Lists']);
         $this->_subscribers_api->RemoveBannedEmails($jobdetails['Lists'], $sendqueue, 'splittest');
         $this->_subscribers_api->RemoveUnsubscribedEmails($jobdetails['Lists'], $sendqueue, 'splittest');
         if (SENDSTUDIO_DATABASE_TYPE == 'pgsql') {
             $this->Db->OptimizeTable(SENDSTUDIO_TABLEPREFIX . "queues");
         }
         $jobdetails['SendSize'] = $this->_subscribers_api->QueueSize($sendqueue, 'splittest');
         $jobdetails['Stats'] = array();
         $jobdetails['SendQueue'] = $sendqueue;
         /**
          * Delete the old user stats allocations.
          * They were all allocated under one stat/job before so the user recorded their send info
          * so they couldn't set up split test sends and go over their send quota.
          *
          * Now, we need to re-allocate them per newsletter being sent.
          */
         $this->_stats_api->DeleteUserStats($jobinfo['ownerid'], $this->_jobid);
         $statids = array();
         foreach ($jobdetails['newsletters'] as $newsletterid) {
             $newsletterstats = $jobdetails;
             $newsletterstats['Job'] = $jobid;
             $newsletterstats['Queue'] = $sendqueue;
             $newsletterstats['SentBy'] = $queueinfo['ownerid'];
             $newsletterstats['SendType'] = 'splittest';
             $newsletterstats['Newsletter'] = $newsletterid;
             $newsletterstats['Lists'] = $jobdetails['sendingto']['Lists'];
             $newsletterstats['SendCriteria'] = $jobdetails['SendCriteria'];
             $statid = $this->_stats_api->SaveNewsletterStats($newsletterstats);
             $statids[] = $statid;
             $jobdetails['Stats'][$newsletterid] = $statid;
             $this->_stats_api->RecordUserStats($jobinfo['ownerid'], $this->_jobid, $jobdetails['SendSize'], $jobdetails['SendStartTime'], $statid);
         }
         $this->SaveSplitStats($jobdetails['splitid'], $this->_jobid, $statids);
         /**
          * If it's a percentage send,
          * work out the number of emails to send for the first percentage
          * It gets stored in the jobdetails array so it can be saved in the database.
          */
         if ($this->splitcampaign_details['splittype'] == 'percentage') {
             $max_to_email = ceil($this->splitcampaign_details['splitdetails']['percentage'] / 100 * $jobdetails['SendSize']);
             $jobdetails['percentage_send_maximum'] = $max_to_email;
         }
         /**
          * Save the job stat details.
          * Otherwise we could potentially end up with a 'start'ed queue but no stats.
          */
         $this->Set('jobdetails', $jobdetails);
         $this->UpdateJobDetails();
         /**
          * This is to process the 'queueid' later in the code.
          */
         $queueid = $sendqueue;
         // This will make sure that the credit warning emails are also being send out from splittest
         API_USERS::creditEvaluateWarnings($user->GetNewAPI());
     }
     $this->Db->OptimizeTable(SENDSTUDIO_TABLEPREFIX . "queues");
     $queuesize = $this->_subscribers_api->QueueSize($queueid, 'splittest');
     $this->_queueid = $queueid;
     /**
      * If there is a "percentage_send_maximum" variable in the jobdetails array,
      * we are sending to the first part of a 'percentage' split test.
      *
      * We have to send to the rest of the percentage maximum before we pause the job,
      * work out the "best" performing campaign and send to that.
      */
     if (isset($jobdetails['percentage_send_maximum'])) {
         $this->_percentage_send_maximum = (int) $jobdetails['percentage_send_maximum'];
     }
     /**
      * If the _percentage_send_maximum is 0, then "timeout" the job.
      * We must have hit "pause" right at the end of the initial send process or something.
      */
     if ($this->_percentage_send_maximum !== null && $this->_percentage_send_maximum <= 0) {
         $this->TimeoutJob($jobid, $this->splitcampaign_details['splitid'], $this->splitcampaign_details['splitdetails']['hoursafter']);
         IEM::userLogout();
         return true;
     }
     $this->Set('statids', $jobdetails['Stats']);
     $this->Set('jobdetails', $jobdetails);
     $this->Set('jobowner', $jobinfo['ownerid']);
     /**
      * There's nothing left? Just mark it as done.
      */
     if ($queuesize == 0) {
         $this->_FinishJob();
         IEM::userLogout();
         return true;
     }
     $finished = $this->_ActionJob($jobid, $queueid);
     if ($finished) {
         $this->_FinishJob();
     }
     IEM::userLogout();
     return true;
 }