]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - modules/Campaigns/utils.php
Release 6.2.0
[Github/sugarcrm.git] / modules / Campaigns / utils.php
1 <?php
2 if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
3 /*********************************************************************************
4  * SugarCRM Community Edition is a customer relationship management program developed by
5  * SugarCRM, Inc. Copyright (C) 2004-2011 SugarCRM Inc.
6  * 
7  * This program is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU Affero General Public License version 3 as published by the
9  * Free Software Foundation with the addition of the following permission added
10  * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
11  * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
12  * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
13  * 
14  * This program is distributed in the hope that it will be useful, but WITHOUT
15  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16  * FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
17  * details.
18  * 
19  * You should have received a copy of the GNU Affero General Public License along with
20  * this program; if not, see http://www.gnu.org/licenses or write to the Free
21  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22  * 02110-1301 USA.
23  * 
24  * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
25  * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
26  * 
27  * The interactive user interfaces in modified source and object code versions
28  * of this program must display Appropriate Legal Notices, as required under
29  * Section 5 of the GNU Affero General Public License version 3.
30  * 
31  * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
32  * these Appropriate Legal Notices must retain the display of the "Powered by
33  * SugarCRM" logo. If the display of the logo is not reasonably feasible for
34  * technical reasons, the Appropriate Legal Notices must display the words
35  * "Powered by SugarCRM".
36  ********************************************************************************/
37
38 /*********************************************************************************
39
40  * Description:  Defines the English language pack for the base application.
41  * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
42  * All Rights Reserved.
43  * Contributor(s): ______________________________________..
44  ********************************************************************************/
45
46 /*
47  *returns a list of objects a message can be scoped by, the list contacts the current campaign
48  *name and list of all prospects associated with this campaign..
49  *
50  */
51 function get_message_scope_dom($campaign_id, $campaign_name,$db=null, $mod_strings=array()) {
52         
53     //find prospect list attached to this campaign..
54     $query =  "SELECT prospect_list_id, prospect_lists.name "; 
55     $query .= "FROM prospect_list_campaigns ";
56     $query .= "INNER join prospect_lists on prospect_lists.id = prospect_list_campaigns.prospect_list_id ";
57     $query .= "WHERE prospect_lists.deleted = 0 "; 
58     $query .= "AND prospect_list_campaigns.deleted=0 "; 
59     $query .= "AND campaign_id='".$campaign_id."'";
60     $query.=" and prospect_lists.list_type not like 'exempt%'";
61     
62     if (empty($db)) {
63         $db = DBManagerFactory::getInstance();
64     }
65     if (empty($mod_strings) or !isset($mod_strings['LBL_DEFAULT'])) {
66         global $current_language;
67         $mod_strings = return_module_language($current_language, 'Campaigns');
68     }
69     
70     //add campaign to the result array.
71     //$return_array[$campaign_id]= $campaign_name . ' (' . $mod_strings['LBL_DEFAULT'] . ')';
72     
73     $result=$db->query($query);
74     while(($row=$db->fetchByAssoc($result))!= null) {
75         $return_array[$row['prospect_list_id']]=$row['name'];
76     }
77     if (empty($return_array)) $return_array=array();    
78     else return $return_array;
79 }
80 /**
81  * Return bounce handling mailboxes for campaign.
82  *
83  * @param unknown_type $emails
84  * @param unknown_type $get_box_name, Set it to false if want to get "From Name" other than the InboundEmail Name.
85  * @return $get_name=true, bounce handling mailboxes' name; $get_name=false, bounce handling mailboxes' from name.
86  */
87 function get_campaign_mailboxes(&$emails, $get_name=true) {
88     if (!class_exists('InboundEmail')) {
89         require('modules/InboundEmail/InboundEmail.php');
90     }
91     $query =  "select id,name,stored_options from inbound_email where mailbox_type='bounce' and status='Active' and deleted='0'"; 
92     $db = DBManagerFactory::getInstance();
93     $result=$db->query($query);
94     while(($row=$db->fetchByAssoc($result))!= null) {
95         if($get_name) {
96                 $return_array[$row['id']] = $row['name'];
97         } else {
98                 $return_array[$row['id']]= InboundEmail::get_stored_options('from_name',$row['name'],$row['stored_options']);
99         }
100         $emails[$row['id']]=InboundEmail::get_stored_options('from_addr','nobody@example.com',$row['stored_options']);
101     }
102
103     if (empty($return_array)) $return_array=array(''=>'');  
104     return $return_array;
105     
106 }
107
108 function get_campaign_mailboxes_with_stored_options() {
109         $ret = array();
110         
111     if(!class_exists('InboundEmail')) {
112         require('modules/InboundEmail/InboundEmail.php');
113     }
114     
115     $q = "SELECT id, name, stored_options FROM inbound_email WHERE mailbox_type='bounce' AND status='Active' AND deleted='0'"; 
116     
117     $db = DBManagerFactory::getInstance();
118     
119     $r = $db->query($q);
120     
121     while($a = $db->fetchByAssoc($r)) {
122         $ret[$a['id']] = unserialize(base64_decode($a['stored_options']));
123     }
124         return $ret;
125 }
126
127 function log_campaign_activity($identifier, $activity, $update=true, $clicked_url_key=null) {
128
129     $return_array = array();
130         
131     $db = DBManagerFactory::getInstance();
132
133
134
135      //check to see if the identifier has been replaced with Banner string
136     if($identifier == 'BANNER' && isset($clicked_url_key)  && !empty($clicked_url_key))
137     {
138         // create md5 encrypted string using the client ip, this will be used for tracker id purposes
139         $enc_id = 'BNR'.md5($_SERVER['REMOTE_ADDR']);   
140         
141         //default the identifier to ip address
142         $identifier = $enc_id;
143         
144         //if user has chosen to not use this mode of id generation, then replace identifier with plain guid.
145         //difference is that guid will generate a new campaign log for EACH CLICK!!
146         //encrypted generation will generate 1 campaign log and update the hit counter for each click
147         if(isset($sugar_config['campaign_banner_id_generation'])  && $sugar_config['campaign_banner_id_generation'] != 'md5'){
148             $identifier = create_guid(); 
149         }
150
151         //retrieve campaign log.  
152         $trkr_query = "select * from campaign_log where target_tracker_key='$identifier ' and related_id = '$clicked_url_key'";
153         $current_trkr=$db->query($trkr_query);
154         $row=$db->fetchByAssoc($current_trkr);
155
156         //if campaign log is not retrieved (this is a new ip address or we have chosen to create 
157         //unique entries for each click
158         if($row==null  || empty($row)){ 
159
160         
161                 //retrieve campaign id
162                 $trkr_query = "select ct.campaign_id from campaign_trkrs ct, campaigns c where c.id = ct.campaign_id and ct.id = '$clicked_url_key'";
163                 $current_trkr=$db->query($trkr_query);
164                 $row=$db->fetchByAssoc($current_trkr);
165             
166         
167                 //create new campaign log with minimal info.  Note that we are creating new unique id
168                 //as target id, since we do not link banner/web campaigns to any users
169         
170                 $data['target_id']="'" . create_guid() . "'";
171                 $data['target_type']= "'Prospects'";
172                 $data['id']="'" . create_guid() . "'";
173                 $data['campaign_id']="'" . $row['campaign_id'] . "'";
174                 $data['target_tracker_key']="'" . $identifier . "'";
175                 $data['activity_type']="'" .  $activity . "'";
176                 $data['activity_date']="'" . TimeDate::getInstance()->nowDb() . "'";
177                 $data['hits']=1;
178                 if (!empty($clicked_url_key)) {
179                     $data['related_id']="'".$clicked_url_key."'";
180                     $data['related_type']="'".'CampaignTrackers'."'";               
181                 }
182         
183                 //values for return array..
184                 $return_array['target_id']=$data['target_id'];
185                 $return_array['target_type']=$data['target_type'];       
186         
187                 //create insert query for new campaign log
188                 $insert_query="INSERT into campaign_log (" . implode(",",array_keys($data)) . ")"; 
189                 $insert_query.=" VALUES  (" . implode(",",array_values($data)) . ")"; 
190                 $db->query($insert_query);
191             }else{
192
193                 //campaign log already exists, so just set the return array and update hits column
194                 $return_array['target_id']= $row['target_id'];
195                 $return_array['target_type']= $row['target_type'];      
196                 $query1="update campaign_log set hits=hits+1 where id='{$row['id']}'";
197                 $current=$db->query($query1);
198                 
199                 
200            }
201
202         //return array and exit                
203         return $return_array;
204
205     }
206     
207     
208     
209     $query1="select * from campaign_log where target_tracker_key='$identifier' and activity_type='$activity'";
210     if (!empty($clicked_url_key)) {
211         $query1.=" AND related_id='$clicked_url_key'";
212     }
213     $current=$db->query($query1);
214     $row=$db->fetchByAssoc($current);
215
216         if ($row==null) {   
217             $query="select * from campaign_log where target_tracker_key='$identifier' and activity_type='targeted'";
218             $targeted=$db->query($query);
219             $row=$db->fetchByAssoc($targeted);
220             
221             //if activity is removed and target type is users, then a user is trying to opt out
222             //of emails.  This is not possible as Users Table does not have opt out column. 
223             if ($row  && (strtolower($row['target_type']) == 'users' &&  $activity == 'removed' )) {
224                 $return_array['target_id']= $row['target_id'];
225                 $return_array['target_type']= $row['target_type']; 
226                 return $return_array;
227             }
228             elseif ($row){                
229                 $data['id']="'" . create_guid() . "'";
230                 $data['campaign_id']="'" . $row['campaign_id'] . "'";
231                 $data['target_tracker_key']="'" . $identifier . "'";
232                 $data['target_id']="'" .  $row['target_id'] . "'";
233                 $data['target_type']="'" .  $row['target_type'] . "'";
234                 $data['activity_type']="'" .  $activity . "'";
235                 $data['activity_date']="'" . TimeDate::getInstance()->nowDb() . "'";
236                 $data['list_id']="'" .  $row['list_id'] . "'";
237                 $data['marketing_id']="'" .  $row['marketing_id'] . "'";
238                 $data['hits']=1;
239                 if (!empty($clicked_url_key)) {
240                     $data['related_id']="'".$clicked_url_key."'";
241                     $data['related_type']="'".'CampaignTrackers'."'";               
242                 }
243                 //values for return array..
244                 $return_array['target_id']=$row['target_id'];
245                 $return_array['target_type']=$row['target_type'];       
246                 $insert_query="INSERT into campaign_log (" . implode(",",array_keys($data)) . ")"; 
247                 $insert_query.=" VALUES  (" . implode(",",array_values($data)) . ")"; 
248                 $db->query($insert_query);
249             }
250         } else {
251     
252             $return_array['target_id']= $row['target_id'];
253             $return_array['target_type']= $row['target_type'];      
254     
255             $query1="update campaign_log set hits=hits+1 where id='{$row['id']}'";
256             $current=$db->query($query1);
257             
258         }
259         //check to see if this is a removal action
260         if ($row  && $activity == 'removed' ) {
261             //retrieve campaign and check it's type, we are looking for newsletter Campaigns
262             $query = "SELECT campaigns.* FROM campaigns WHERE campaigns.id = '".$row['campaign_id']."' ";
263             $result = $db->query($query);
264             if(!empty($result)) 
265             {
266                 $c_row = $db->fetchByAssoc($result);
267     
268                 //if type is newsletter, then add campaign id to return_array for further processing.
269                 if(isset($c_row['campaign_type']) && $c_row['campaign_type'] == 'NewsLetter'){
270                     $return_array['campaign_id']=$c_row['id'];
271                 }
272             }
273         }            
274         return $return_array;
275     }
276
277
278 function campaign_log_lead_entry($campaign_id, $parent_bean,$child_bean,$activity_type){
279         global $timedate;        
280                                   
281
282                     //create campaign tracker id and retrieve related bio bean                 
283                      $tracker_id = create_guid();                          
284                     //create new campaign log record.
285                     $campaign_log = new CampaignLog();
286                     $campaign_log->campaign_id = $campaign_id;
287                     $campaign_log->target_tracker_key = $tracker_id;
288                     $campaign_log->related_id = $parent_bean->id;
289                     $campaign_log->related_type = $parent_bean->module_dir;
290                     $campaign_log->target_id = $child_bean->id;
291                     $campaign_log->target_type = $child_bean->module_dir;
292                     $campaign_log->activity_date = $timedate->now();
293                     $campaign_log->activity_type = $activity_type;
294                     //save the campaign log entry
295                     $campaign_log->save();                                        
296 }
297
298 function get_campaign_urls($campaign_id) {
299     $return_array=array();
300
301     if (!empty($campaign_id)) {
302         
303         $db = DBManagerFactory::getInstance();
304
305         $query1="select * from campaign_trkrs where campaign_id='$campaign_id' and deleted=0";
306         $current=$db->query($query1);
307         while (($row=$db->fetchByAssoc($current)) != null) {
308             $return_array['{'.$row['tracker_name'].'}']=$row['tracker_name'] . ' : ' . $row['tracker_url'];
309         }       
310     }
311     return $return_array;
312 }
313
314 /**
315  * Queries for the list
316  */
317 function get_subscription_lists_query($focus, $additional_fields = null) { 
318     //get all prospect lists belonging to Campaigns of type newsletter
319     $all_news_type_pl_query = "select c.name, pl.list_type, plc.campaign_id, plc.prospect_list_id";
320     if(is_array($additional_fields) && !empty($additional_fields)) $all_news_type_pl_query .= ', ' . implode(', ', $additional_fields); 
321     $all_news_type_pl_query .= " from prospect_list_campaigns plc , prospect_lists pl, campaigns c "; 
322     
323     
324         $all_news_type_pl_query .= "where plc.campaign_id = c.id ";
325     $all_news_type_pl_query .= "and plc.prospect_list_id = pl.id ";
326     $all_news_type_pl_query .= "and c.campaign_type = 'NewsLetter'  and pl.deleted = 0 and c.deleted=0 and plc.deleted=0 ";
327     $all_news_type_pl_query .= "and (pl.list_type like 'exempt%' or pl.list_type ='default') ";
328     
329     $all_news_type_list =$focus->db->query($all_news_type_pl_query);
330
331     //build array of all newsletter campaigns  
332     $news_type_list_arr = array();
333     while ($row = $focus->db->fetchByAssoc($all_news_type_list)){$news_type_list_arr[] = $row;}        
334
335     //now get all the campaigns that the current user is assigned to
336     $all_plp_current = "select prospect_list_id from prospect_lists_prospects where related_id = '$focus->id' and deleted = 0 ";
337
338     //build array of prospect lists that this user belongs to
339     $current_plp =$focus->db->query($all_plp_current );
340     $current_plp_arr = array();
341     while ($row = $focus->db->fetchByAssoc($current_plp)){$current_plp_arr[] = $row;}
342     
343     return array('current_plp_arr' => $current_plp_arr, 'news_type_list_arr' => $news_type_list_arr);
344 }
345 /*
346  * This function takes in a bean from a lead, propsect, or contact and returns an array containing 
347  * all subscription lists that the bean is a part of, and all the subscriptions that the bean is not 
348  * a part of.  The array elements have the key names of "subscribed" and "unsusbscribed".  These elements contain an array
349  * of the corresponding list.  In other words, the "subscribed" element holds another array that holds the subscription information. 
350  * 
351  * The subscription information is a concatenated string that holds the prospect list id and the campaign id, seperated by at "@" character.
352  * To parse these information string into something more usable, use the "process subscriptions()" function
353  *  
354  * */
355 function get_subscription_lists($focus, $descriptions = false) {
356     $subs_arr = array();
357     $unsubs_arr = array();
358
359     $results = get_subscription_lists_query($focus, $descriptions);
360
361     $news_type_list_arr = $results['news_type_list_arr'];
362     $current_plp_arr = $results['current_plp_arr'];
363     
364    //For each  prospect list of type 'NewsLetter', check to see if current user is already in list, 
365     foreach($news_type_list_arr as $news_list){
366         $match = 'false';
367
368         //perform this check against each prospect list this user belongs to
369         foreach($current_plp_arr as $current_list_key => $current_list){//echo " new entry from current lists user is subscribed to-------------"; 
370             //compare current user list id against newsletter id
371             if ($news_list['prospect_list_id'] == $current_list['prospect_list_id']){
372                 //if id's match, user is subscribed to this list, check to see if this is an exempt list,
373                 if(strpos($news_list['list_type'],  'exempt')!== false){
374                     //this is an exempt list, so process
375                     if(array_key_exists($news_list['name'],$subs_arr)){
376                         //first, add to unsubscribed array
377                         $unsubs_arr[$news_list['name']] = $subs_arr[$news_list['name']];
378                         //now remove from exempt subscription list
379                         unset($subs_arr[$news_list['name']]);
380                     }else{
381                         //we know this is an exempt list the user belongs to, but the
382                         //non exempt list has not been processed yet, so just add to exempt array
383                         $unsubs_arr[$news_list['name']] = "prospect_list@".$news_list['prospect_list_id']."@campaign@".$news_list['campaign_id'];
384                     }
385                     $match = 'false';//although match is false, this is an exempt array, so 
386                     //it will not be added a second time down below
387                 }else{
388                     //this list is not exempt, and user is subscribed, so add to subscribed array, and unset from the unsubs_arr
389                     //as long as this list is not in exempt array
390                         $temp = "prospect_list@".$news_list['prospect_list_id']."@campaign@".$news_list['campaign_id'];
391                         if(!array_search($temp,$unsubs_arr)){
392                         $subs_arr[$news_list['name']] = "prospect_list@".$news_list['prospect_list_id']."@campaign@".$news_list['campaign_id'];
393                         $match = 'true'; 
394                         //unset($unsubs_arr[$news_list['name']]);
395                     }
396                 }
397             }else{
398                 //do nothing, there is no match
399                 }
400         }
401          //if this newsletter id never matched a user subscription..
402          //..then add to available(unsubscribed) NewsLetters if list is not of type exempt
403          if(($match == 'false') && (strpos($news_list['list_type'],  'exempt') === false)){  
404             $unsubs_arr[$news_list['name']] = "prospect_list@".$news_list['prospect_list_id']."@campaign@".$news_list['campaign_id'];                
405         }
406     
407     }
408     $return_array['unsubscribed'] = $unsubs_arr;
409     $return_array['subscribed'] = $subs_arr;
410     return $return_array;
411 }
412
413 /**
414  * same function as get_subscription_lists, but with the data seperated in an associated array
415  */
416 function get_subscription_lists_keyed($focus) {
417     $subs_arr = array();
418     $unsubs_arr = array();
419
420     $results = get_subscription_lists_query($focus, array('c.content', 'c.frequency'));
421       
422     $news_type_list_arr = $results['news_type_list_arr'];
423     $current_plp_arr = $results['current_plp_arr'];
424     
425    //For each  prospect list of type 'NewsLetter', check to see if current user is already in list, 
426     foreach($news_type_list_arr as $news_list){
427         $match = false;
428         
429         $news_list_data = array('prospect_list_id' => $news_list['prospect_list_id'],
430                                 'campaign_id'      => $news_list['campaign_id'],
431                                 'description'      => $news_list['content'],
432                                 'frequency'        => $news_list['frequency']);
433
434         //perform this check against each prospect list this user belongs to
435         foreach($current_plp_arr as $current_list_key => $current_list){//echo " new entry from current lists user is subscribed to-------------"; 
436             //compare current user list id against newsletter id
437             if ($news_list['prospect_list_id'] == $current_list['prospect_list_id']){
438                 //if id's match, user is subscribed to this list, check to see if this is an exempt list,
439
440                 if($news_list['list_type'] == 'exempt'){
441                     //this is an exempt list, so process
442                     if(array_key_exists($news_list['name'],$subs_arr)){
443                         //first, add to unsubscribed array
444                         $unsubs_arr[$news_list['name']] = $subs_arr[$news_list['name']];
445                         //now remove from exempt subscription list
446                         unset($subs_arr[$news_list['name']]);
447                     }else{
448                         //we know this is an exempt list the user belongs to, but the
449                         //non exempt list has not been processed yet, so just add to exempt array
450                         $unsubs_arr[$news_list['name']] = $news_list_data;
451                     }
452                     $match = false;//although match is false, this is an exempt array, so 
453                     //it will not be added a second time down below
454                 }else{
455                     //this list is not exempt, and user is subscribed, so add to subscribed array
456                     //as long as this list is not in exempt array
457                     if(!array_key_exists($news_list['name'],$unsubs_arr)){
458                         $subs_arr[$news_list['name']] = $news_list_data;
459                         $match = 'true';   
460                     }
461                 }
462             }else{
463                 //do nothing, there is no match
464                 }
465         }
466          //if this newsletter id never matched a user subscription..
467          //..then add to available(unsubscribed) NewsLetters if list is not of type exempt
468          if(($match == false) && ($news_list['list_type'] != 'exempt')){  
469             $unsubs_arr[$news_list['name']] = $news_list_data;                
470         }
471     
472     }
473
474     $return_array['unsubscribed'] = $unsubs_arr;
475     $return_array['subscribed'] = $subs_arr; 
476     return $return_array;
477 }
478
479
480
481 /*
482  * This function will take an array of strings that have been created by the "get_subscription_lists()" method
483  * and parses it into an array.  The returned array has it's key's labeled in a specific fashion.  
484  * 
485  * Each string produces a campaign and a prospect id.  The keys are appended with a number specifying the order 
486  * it was process in.  So an input array containing 3 strings will have the following key values:
487  * "prospect_list0", "campaign0"
488  * "prospect_list1", "campaign1"
489  * "prospect_list2", "campaign2" 
490  * 
491  * */
492 function process_subscriptions($subscription_string_to_parse) {
493     $subs_change = array();
494
495     //parse through and build list of id's'.  We are retrieving the campaign_id and 
496     //the prospect_list id from the selected subscriptions 
497     $i = 0;
498     foreach($subscription_string_to_parse as $subs_changes){
499         $subs_changes = trim($subs_changes);
500         if(!empty($subs_changes)){
501             $ids_arr = explode("@", $subs_changes);
502             $subs_change[$ids_arr[0].$i] = $ids_arr[1];
503             $subs_change[$ids_arr[2].$i] = $ids_arr[3];
504             $i = $i+1;
505         }
506     }
507     return $subs_change;
508 }
509
510
511     /*This function is used by the Manage Subscriptions page in order to add the user
512      * to the default prospect lists of the passed in campaign 
513      * Takes in campaign and prospect list id's we are subscribing to.  
514      * It also takes in a bean of the user (lead,target,prospect) we are subscribing
515      * */
516     function subscribe($campaign, $prospect_list, $focus, $default_list = false) {
517             $relationship = strtolower($focus->getObjectName()).'s';
518
519             //--grab all the lists for the passed in campaign id
520             $pl_qry ="select id, list_type from prospect_lists where id in (select prospect_list_id from prospect_list_campaigns "; 
521             $pl_qry .= "where campaign_id = '$campaign') and deleted = 0 ";
522             $GLOBALS['log']->debug("In Campaigns Util: subscribe function, about to run query: ".$pl_qry );
523             $pl_qry_result = $focus->db->query($pl_qry);
524     
525             //build the array of all prospect_lists 
526             $pl_arr = array();
527             while ($row = $focus->db->fetchByAssoc($pl_qry_result)){$pl_arr[] = $row;}
528     
529             //--grab all the prospect_lists this user belongs to
530             $curr_pl_qry ="select prospect_list_id, related_id  from prospect_lists_prospects ";
531             $curr_pl_qry .="where related_id = '$focus->id'  and deleted = 0 ";
532             $GLOBALS['log']->debug("In Campaigns Util: subscribe function, about to run query: ".$curr_pl_qry );
533             $curr_pl_qry_result = $focus->db->query($curr_pl_qry);
534     
535             //build the array of all prospect lists that this current user belongs to
536             $curr_pl_arr = array();
537             while ($row = $focus->db->fetchByAssoc($curr_pl_qry_result)){$curr_pl_arr[] = $row;}
538     
539             //search through prospect lists for this campaign and identifiy the "unsubscription list"
540             $exempt_id = '';
541            foreach($pl_arr as $subscription_list){
542                 if(strpos($subscription_list['list_type'],  'exempt')!== false){
543                     $exempt_id = $subscription_list['id'];
544                 }
545                           
546                 if($subscription_list['list_type'] == 'default' && $default_list) {
547                     $prospect_list = $subscription_list['id'];
548                 }
549            } 
550            
551            //now that we have exempt (unsubscription) list id, compare against user list id's
552            if(!empty($exempt_id)){
553             $exempt_array['exempt_id'] = $exempt_id;
554                 
555                foreach($curr_pl_arr as $curr_subscription_list){
556                     if($curr_subscription_list['prospect_list_id'] == $exempt_id){
557                         //--if we are in here then user is subscribing to a list in which they are exempt.
558                         // we need to remove the user from this unsubscription list.
559                         //Begin by retrieving unsubscription prospect list
560                         $exempt_subscription_list = new ProspectList();
561                         
562                                 
563                         $exempt_result = $exempt_subscription_list->retrieve($exempt_id);
564                         if($exempt_result == null)
565                         {//error happened while retrieving this list
566                             return;
567                         }
568                         //load realationships and delete user from unsubscription list
569                         $exempt_subscription_list->load_relationship($relationship);
570                         $exempt_subscription_list->$relationship->delete($exempt_id,$focus->id);
571                         
572                     }
573                } 
574            }    
575     
576             //Now we need to check if user is already in subscription list
577             $already_here = 'false';
578             //for each list user is subscribed to, compare id's with current list id'
579             foreach($curr_pl_arr as $user_list){
580                 if(in_array($prospect_list, $user_list)){
581                     //if user already exists, then set flag to true
582                     $already_here = 'true';    
583                 }    
584             }
585             if($already_here ==='true'){
586                 //do nothing, user is already subscribed
587             }else{
588                 //user is not subscribed already, so add to subscription list
589                 $subscription_list = new ProspectList();
590                 $subs_result = $subscription_list->retrieve($prospect_list);
591                 if($subs_result == null)
592                 {//error happened while retrieving this list, iterate and continue
593                     return;
594                 }
595                 //load subscription list and add this user
596                 $GLOBALS['log']->debug("In Campaigns Util, loading relationship: ".$relationship);
597                 $subscription_list->load_relationship($relationship);
598                 $subscription_list->$relationship->add($focus->id);
599             }
600 }
601
602
603     /*This function is used by the Manage Subscriptions page in order to add the user
604      * to the exempt prospect lists of the passed in campaign 
605      * Takes in campaign and focus parameters.  
606      * */
607     function unsubscribe($campaign, $focus) {
608         $relationship = strtolower($focus->getObjectName()).'s';
609         //--grab all the list for this campaign id   
610         $pl_qry ="select id, list_type from prospect_lists where id in (select prospect_list_id from prospect_list_campaigns "; 
611         $pl_qry .= "where campaign_id = '$campaign') and deleted = 0 ";
612         $pl_qry_result = $focus->db->query($pl_qry);
613         //build the array with list information
614         $pl_arr = array();
615         $GLOBALS['log']->debug("In Campaigns Util, about to run query: ".$pl_qry);
616         while ($row = $focus->db->fetchByAssoc($pl_qry_result)){$pl_arr[] = $row;}
617     
618         //retrieve lists that this user belongs to
619         $curr_pl_qry ="select prospect_list_id, related_id  from prospect_lists_prospects ";
620         $curr_pl_qry .="where related_id = '$focus->id'  and deleted = 0 ";
621         $GLOBALS['log']->debug("In Campaigns Util, unsubscribe function about to run query: ".$curr_pl_qry );
622         $curr_pl_qry_result = $focus->db->query($curr_pl_qry);
623         
624         //build the array with current user list information
625         $curr_pl_arr = array();
626         while ($row = $focus->db->fetchByAssoc($curr_pl_qry_result)){$curr_pl_arr[] = $row;}
627          //check to see if user is already there in prospect list
628         $already_here = 'false';
629         $exempt_id = '';
630
631         foreach($curr_pl_arr as $user_list){
632                 foreach($pl_arr as $v){
633                         //if list is exempt list
634                 if($v['list_type'] == 'exempt'){
635                         //save the exempt list id for later use
636                         $exempt_id = $v['id'];
637                                         //check to see if user is already in this exempt list
638                         if(in_array($v['id'], $user_list)){
639                                 $already_here = 'true';
640                         }
641                         
642                         break 2;    
643                 }
644                 }    
645         }
646                 
647         //unsubscribe subscripted newsletter
648         foreach($pl_arr as $subscription_list){
649                         //create a new instance of the prospect list
650                 $exempt_list = new ProspectList();
651                 $exempt_list->retrieve($subscription_list['id']);
652                 $exempt_list->load_relationship($relationship);  
653                         //if list type is default, then delete the relationship
654             //if list type is exempt, then add the relationship to unsubscription list
655             if($subscription_list['list_type'] == 'exempt') {
656                         $exempt_list->$relationship->add($focus->id);
657             }elseif($subscription_list['list_type'] == 'default' || $subscription_list['list_type'] == 'test'){
658                 //if list type is default or test, then delete the relationship
659                 //$exempt_list->$relationship->delete($subscription_list['id'],$focus->id);
660             }
661             
662         } 
663
664         if($already_here =='true'){
665             //do nothing, user is already exempted
666         
667         }else{
668             //user is not exempted yet , so add to unsubscription list
669             
670             
671             $exempt_result = $exempt_list->retrieve($exempt_id);
672             if($exempt_result == null)
673             {//error happened while retrieving this list
674                 return;
675             }
676             $GLOBALS['log']->debug("In Campaigns Util, loading relationship: ".$relationship);
677             $exempt_list->load_relationship($relationship);
678             $exempt_list->$relationship->add($focus->id);
679         }
680     
681     }
682     
683     
684     /*
685      *This function will return a string to the newsletter wizard if campaign check 
686      *does not return 100% healthy. 
687      */
688     function diagnose()
689     {
690         global $mod_strings;
691         global $current_user;
692         $msg = " <table class='detail view small' width='100%'><tr><td> ".$mod_strings['LNK_CAMPAIGN_DIGNOSTIC_LINK']."</td></tr>";
693         //Start with email components
694         //monitored mailbox section
695         $focus = new Administration();
696         $focus->retrieveSettings(); //retrieve all admin settings.
697         
698         
699         //run query for mail boxes of type 'bounce' 
700         $email_health = 0;
701         $email_components = 2;
702         $mbox_qry = "select * from inbound_email where deleted ='0' and mailbox_type = 'bounce'";
703         $mbox_res = $focus->db->query($mbox_qry);
704         
705         $mbox = array();
706         while ($mbox_row = $focus->db->fetchByAssoc($mbox_res)){$mbox[] = $mbox_row;}
707         //if the array is not empty, then set "good" message
708         if(isset($mbox) && count($mbox)>0){
709             //everything is ok, do nothing
710         
711         }else{
712             //if array is empty, then increment health counter
713             $email_health =$email_health +1;
714             $msg  .=  "<tr><td ><font color='red'><b>". $mod_strings['LBL_MAILBOX_CHECK1_BAD']."</b></font></td></tr>";
715         }
716         
717         
718         if (strstr($focus->settings['notify_fromaddress'], 'example.com')){
719             //if "from_address" is the default, then set "bad" message and increment health counter
720             $email_health =$email_health +1;
721             $msg .= "<tr><td ><font color='red'><b> ".$mod_strings['LBL_MAILBOX_CHECK2_BAD']." </b></font></td></tr>";
722         }else{
723             //do nothing, address has been changed
724         }
725         //if health counter is above 1, then show admin link            
726         if($email_health>0){
727             if (is_admin($current_user)){
728                 $msg.="<tr><td ><a href='index.php?module=Campaigns&action=WizardEmailSetup";
729                 if(isset($_REQUEST['return_module'])){
730                     $msg.="&return_module=".$_REQUEST['return_module'];
731                 }
732                 if(isset($_REQUEST['return_action'])){
733                     $msg.="&return_action=".$_REQUEST['return_action'];
734                 }                
735                 $msg.="'>".$mod_strings['LBL_EMAIL_SETUP_WIZ']."</a></td></tr>";
736             }else{
737                 $msg.="<tr><td >".$mod_strings['LBL_NON_ADMIN_ERROR_MSG']."</td></tr>";
738                 
739             }    
740             
741         }      
742         
743
744         // proceed with scheduler components 
745         
746         //create and run the scheduler queries 
747         $sched_qry = "select job, name, status from schedulers where deleted = 0 and status = 'Active'";
748         $sched_res = $focus->db->query($sched_qry);
749         $sched_health = 0;
750         $sched = array();
751         $check_sched1 = 'function::runMassEmailCampaign';
752         $check_sched2 = 'function::pollMonitoredInboxesForBouncedCampaignEmails';
753         $sched_mes = '';
754         $sched_mes_body = '';
755         $scheds = array();
756         
757         while ($sched_row = $focus->db->fetchByAssoc($sched_res)){$scheds[] = $sched_row;}
758         //iterate through and see which jobs were found
759         foreach ($scheds as $funct){
760           if( ($funct['job']==$check_sched1)  ||   ($funct['job']==$check_sched2)){
761                 if($funct['job']==$check_sched1){
762                     $check_sched1 ="found";
763                 }else{
764                     $check_sched2 ="found";
765                 }  
766                 
767           }
768         }
769         //determine if error messages need to be displayed for schedulers
770         if($check_sched2 != 'found'){
771             $sched_health =$sched_health +1;
772             $msg.= "<tr><td><font color='red'><b>".$mod_strings['LBL_SCHEDULER_CHECK1_BAD']."</b></font></td></tr>";
773         }
774         if($check_sched1 != 'found'){
775             $sched_health =$sched_health +1;
776             $msg.= "<tr><td><font color='red'><b>".$mod_strings['LBL_SCHEDULER_CHECK2_BAD']."</b></font></td></tr>";
777         }
778         //if health counter is above 1, then show admin link            
779         if($sched_health>0){
780             global $current_user;
781             if (is_admin($current_user)){
782                 $msg.="<tr><td ><a href='index.php?module=Schedulers&action=index'>".$mod_strings['LBL_SCHEDULER_LINK']."</a></td></tr>";
783             }else{
784                 $msg.="<tr><td >".$mod_strings['LBL_NON_ADMIN_ERROR_MSG']."</td></tr>";
785             }    
786             
787         }      
788
789         //determine whether message should be returned
790         if(($sched_health + $email_health)>0){
791             $msg  .= "</table> ";    
792         }else{
793             $msg = '';
794         }
795         return $msg;        
796     }
797     
798     
799 /**
800  * Handle campaign log entry creation for mail-merge activity. The function will be called by the soap component.
801  * 
802  * @param String campaign_id Primary key of the campaign
803  * @param array targets List of keys for entries from prospect_lists_prosects table
804  */
805  function campaign_log_mail_merge($campaign_id, $targets) {
806     
807     $campaign= new Campaign();
808     $campaign->retrieve($campaign_id);
809        
810     if (empty($campaign->id)) {
811         $GLOBALS['log']->debug('set_campaign_merge: Invalid campaign id'. $campaign_id);
812     } else {
813         foreach ($targets as $target_list_id) {
814             $pl_query = "select * from prospect_lists_prospects where id='$target_list_id'";
815             $result=$GLOBALS['db']->query($pl_query);
816             $row=$GLOBALS['db']->fetchByAssoc($result);
817             if (!empty($row)) {
818                 write_mail_merge_log_entry($campaign_id,$row);
819             }
820         }        
821     }
822  
823  }
824 /**
825  * Function creates a campaign_log entry for campaigns processesed using the mail-merge feature. If any entry
826  * exist the hit counter is updated. target_tracker_key is used to locate duplicate entries.
827  * @param string campaign_id Primary key of the campaign
828  * @param array $pl_row A row of data from prospect_lists_prospects table.
829  */
830 function write_mail_merge_log_entry($campaign_id,$pl_row) {
831     
832     //Update the log entry if it exists.
833     $update="update campaign_log set hits=hits+1 where campaign_id='$campaign_id' and target_tracker_key='" . $pl_row['id'] . "'";
834     $result=$GLOBALS['db']->query($update);
835     
836     //get affected row count...
837     $count=$GLOBALS['db']->getAffectedRowCount();
838     if ($count==0) {
839         $data=array();
840         
841         $data['id']="'" . create_guid() . "'";
842         $data['campaign_id']="'" . $campaign_id . "'";
843         $data['target_tracker_key']="'" . $pl_row['id'] . "'";
844         $data['target_id']="'" .  $pl_row['related_id'] . "'";
845         $data['target_type']="'" .  $pl_row['related_type'] . "'";
846         $data['activity_type']="'targeted'";
847         $data['activity_date']="'" . TimeDate::getInstance()->nowDb() . "'";
848         $data['list_id']="'" .  $pl_row['prospect_list_id'] . "'";
849         $data['hits']=1;
850         
851         $insert_query="INSERT into campaign_log (" . implode(",",array_keys($data)) . ")"; 
852         $insert_query.=" VALUES  (" . implode(",",array_values($data)) . ")"; 
853         $GLOBALS['db']->query($insert_query);       
854     }
855 }     
856
857     function track_campaign_prospects($focus){
858                 $delete_query="delete from campaign_log where campaign_id='{$focus->id}' and activity_type='targeted'";
859                 $focus->db->query($delete_query);
860
861                 $query="SELECT prospect_lists.id prospect_list_id from prospect_lists ";
862                 $query.=" INNER JOIN prospect_list_campaigns plc ON plc.prospect_list_id = prospect_lists.id";
863                 $query.=" WHERE plc.campaign_id='{$focus->id}'"; 
864                 $query.=" AND prospect_lists.deleted=0";
865                 $query.=" AND plc.deleted=0";
866                 $query.=" AND prospect_lists.list_type!='test' AND prospect_lists.list_type not like 'exempt%'";                                        
867                 $result=$focus->db->query($query);
868                 while (($row=$focus->db->fetchByAssoc($result))!=null ) {
869                         $prospect_list_id=$row['prospect_list_id'];
870
871                         if ($focus->db->dbType=='oci8') {
872                         } 
873                         else if ($focus->db->dbType=='mssql') {
874                                 $current_date= "'".TimeDate::getInstance()->nowDb()."'";
875                                 $guid = "NEWID()";
876                         }
877                         else {
878                                 $current_date= "'".TimeDate::getInstance()->nowDb()."'";
879                                 $guid = "UUID()";
880                         }
881
882                         $insert_query= "INSERT INTO campaign_log (id,activity_date, campaign_id, target_tracker_key,list_id, target_id, target_type, activity_type";
883                         $insert_query.=')'; 
884                         $insert_query.= " SELECT $guid,$current_date,plc.campaign_id,$guid,plp.prospect_list_id, plp.related_id, plp.related_type,'targeted' ";  
885                         $insert_query.= "FROM prospect_lists_prospects plp ";
886                         $insert_query.= "INNER JOIN prospect_list_campaigns plc ON plc.prospect_list_id = plp.prospect_list_id "; 
887                         $insert_query.= "WHERE plp.prospect_list_id = '{$prospect_list_id}' ";
888                         $insert_query.= "AND plp.deleted=0 ";
889                         $insert_query.= "AND plc.deleted=0 ";
890                         $insert_query.= "AND plc.campaign_id='{$focus->id}'";
891 /*
892                         if ($focus->db->dbType=='oci8') {
893                         }
894                         */
895                         $focus->db->query($insert_query);
896                 }
897         global $mod_strings;
898         //return success message   
899         return $mod_strings['LBL_DEFAULT_LIST_ENTRIES_WERE_PROCESSED'];
900     }
901     
902     function create_campaign_log_entry($campaign_id, $focus, $rel_name, $rel_bean, $target_id = ''){
903         global $timedate;
904         
905         $target_ids = array();
906         //check if this is specified for one target/contact/prospect/lead (from contact/lead detail subpanel)
907         if(!empty($target_id)){
908             $target_ids[] = $target_id;
909         }else{
910             //this is specified for all, so load target/prospect relationships (mark as sent button)
911             $focus->load_relationship($rel_name);
912             $target_ids = $focus->$rel_name->get();
913         
914         }
915         if(count($target_ids)>0){
916             
917           
918             //retrieve the target beans and create campaign log entry
919             foreach($target_ids as $id){
920                  //perform duplicate check
921                  $dup_query = "select id from campaign_log where campaign_id = '$campaign_id' and target_id = '$id'";
922                  $dup_result = $focus->db->query($dup_query);
923                  $row = $focus->db->fetchByAssoc($dup_result);
924
925                 //process if this is not a duplicate campaign log entry
926                 if(empty($row)){
927                     //create campaign tracker id and retrieve related bio bean                 
928                      $tracker_id = create_guid();     
929                      $rel_bean->retrieve($id);
930     
931                     //create new campaign log record.
932                     $campaign_log = new CampaignLog();
933                     $campaign_log->campaign_id = $campaign_id;
934                     $campaign_log->target_tracker_key = $tracker_id;
935                     $campaign_log->target_id = $rel_bean->id;
936                     $campaign_log->target_type = $rel_bean->module_dir;
937                     $campaign_log->activity_type = 'targeted';
938                     $campaign_log->activity_date=$timedate->now();                    
939                     //save the campaign log entry
940                     $campaign_log->save();
941                 }
942             }    
943         }
944     
945     }
946     
947     /*
948      * This function will return an array that has been formatted to work as a Quick Search Object for prospect lists
949      */
950     function getProspectListQSObjects($source = '', $return_field_name='name', $return_field_id='id' ) {
951         global $app_strings;
952         //if source has not been specified, then search across all prospect lists
953         if(empty($source)){
954             $qsProspectList = array('method' => 'query', 
955                                 'modules'=> array('ProspectLists'), 
956                                 'group' => 'and',
957                                 'field_list' => array('name', 'id'),
958                                 'populate_list' => array('prospect_list_name', 'prospect_list_id'), 
959                                 'conditions' => array( array('name'=>'name','op'=>'like_custom','end'=>'%','value'=>'') ),
960                                 'order' => 'name',
961                                 'limit' => '30',
962                                 'no_match_text' => $app_strings['ERR_SQS_NO_MATCH']);
963         }else{
964              //source has been specified use it to tell quicksearch.js which html input to use to get filter value 
965             $qsProspectList = array('method' => 'query', 
966                                 'modules'=> array('ProspectLists'), 
967                                 'group' => 'and',
968                                 'field_list' => array('name', 'id'), 
969                                 'populate_list' => array($return_field_name, $return_field_id), 
970                                 'conditions' => array(
971                                                     array('name'=>'name','op'=>'like_custom','end'=>'%','value'=>''),
972                                                     //this condition has the source parameter defined, meaning the query will take the value specified below
973                                                     array('name'=>'list_type', 'op'=>'like_custom', 'end'=>'%','value'=>'', 'source' => $source)
974                                 ),
975                                 'order' => 'name',
976                                 'limit' => '30',
977                                 'no_match_text' => $app_strings['ERR_SQS_NO_MATCH']);
978                 
979         }
980                             
981         return $qsProspectList;
982     }
983     
984     
985 ?>