]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - modules/EmailMan/EmailMan.php
Release 6.1.4
[Github/sugarcrm.git] / modules / EmailMan / EmailMan.php
1 <?php
2 if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
3 /*********************************************************************************
4  * SugarCRM 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 class EmailMan extends SugarBean{
41         var $id;
42         var $deleted;
43         var $date_created;
44         var $date_modified;
45         var $module;
46         var $module_id;
47         var $marketing_id;
48         var $campaign_id;
49         var $user_id;
50         var $list_id;
51         var $invalid_email;
52         var $from_name;
53         var $from_email;
54         var $in_queue;
55         var $in_queue_date;
56         var $template_id;
57         var $send_date_time;
58         var $table_name = "emailman";
59         var $object_name = "EmailMan";
60         var $module_dir = "EmailMan";
61         var $send_attempts;
62         var $related_id;
63         var $related_type;
64         var $test=false;
65         var $notes_array = array();
66     var $verified_email_marketing_ids =  array();
67         function toString(){
68                 return "EmailMan:\nid = $this->id ,user_id= $this->user_id module = $this->module , related_id = $this->related_id , related_type = $this->related_type ,list_id = $this->list_id, send_date_time= $this->send_date_time\n";
69         }
70
71     // This is used to retrieve related fields from form posts.
72         var $additional_column_fields = array();
73
74         function EmailMan() {
75                 parent::SugarBean();
76
77         }
78
79         var $new_schema = true;
80         
81     function create_new_list_query($order_by, $where,$filter=array(),$params=array(), $show_deleted = 0,$join_type='', $return_array = false,$parentbean=null, $singleSelect = false) {
82                 $query = array('select' => '', 'from' => '', 'where' => '', 'order_by' => '');
83         
84                 
85
86                 if ( ( $this->db->dbType == 'mysql' ) or ( $this->db->dbType == 'oci8' ) )
87                 {
88
89                 $query['select'] = "SELECT $this->table_name.* ,
90                                         campaigns.name as campaign_name,
91                                         email_marketing.name as message_name,
92                                         (CASE related_type
93                                                 WHEN 'Contacts' THEN CONCAT(CONCAT(contacts.first_name, '&nbsp;' ), contacts.last_name)
94                                                 WHEN 'Leads' THEN CONCAT(CONCAT(leads.first_name, '&nbsp;' ), leads.last_name)
95                                                 WHEN 'Accounts' THEN accounts.name
96                                                 WHEN 'Users' THEN CONCAT(CONCAT(users.first_name, ' ' ), users.last_name)
97                                                 WHEN 'Prospects' THEN CONCAT(CONCAT(prospects.first_name, '&nbsp;' ), prospects.last_name)
98                                         END) recipient_name";
99                 }
100             if($this->db->dbType == 'mssql')
101                 {
102                                 $query['select'] = "SELECT $this->table_name.* ,
103                                         campaigns.name as campaign_name,
104                                         email_marketing.name as message_name,
105                                         (CASE related_type
106                                                 WHEN 'Contacts' THEN contacts.first_name + '&nbsp;' + contacts.last_name
107                                                 WHEN 'Leads' THEN  leads.first_name + '&nbsp;' + leads.last_name
108                                                 WHEN 'Accounts' THEN  accounts.name
109                                                 WHEN 'Users' THEN  users.first_name + ' ' + users.last_name                                             
110                                                 WHEN 'Prospects' THEN prospects.first_name + '&nbsp;' + prospects.last_name
111                                         END) recipient_name";
112                 }
113
114                 $query['from'] = "      FROM $this->table_name
115                                         LEFT JOIN users ON users.id = $this->table_name.related_id and $this->table_name.related_type ='Users'
116                                         LEFT JOIN contacts ON contacts.id = $this->table_name.related_id and $this->table_name.related_type ='Contacts'
117                                         LEFT JOIN leads ON leads.id = $this->table_name.related_id and $this->table_name.related_type ='Leads'
118                                         LEFT JOIN accounts ON accounts.id = $this->table_name.related_id and $this->table_name.related_type ='Accounts'
119                                         LEFT JOIN prospects ON prospects.id = $this->table_name.related_id and $this->table_name.related_type ='Prospects'
120                                         LEFT JOIN prospect_lists ON prospect_lists.id = $this->table_name.list_id 
121                     LEFT JOIN email_addr_bean_rel ON email_addr_bean_rel.bean_id = $this->table_name.related_id and $this->table_name.related_type = email_addr_bean_rel.bean_module and email_addr_bean_rel.deleted=0
122                                         LEFT JOIN campaigns ON campaigns.id = $this->table_name.campaign_id
123                                         LEFT JOIN email_marketing ON email_marketing.id = $this->table_name.marketing_id ";
124
125                 $where_auto = " $this->table_name.deleted=0";
126
127         if($where != "")
128                         $query['where'] = "WHERE $where AND ".$where_auto;
129                 else
130                         $query['where'] = "WHERE ".$where_auto;
131
132         if(isset($params['group_by'])) {
133                         $query['order_by'] .= " GROUP BY {$params['group_by']}";        
134                 }                       
135                         
136                 if($order_by != ""){
137                         $query['order_by'] = " ORDER BY $order_by";
138                 }
139         
140                 if ($return_array) {
141                         return $query;
142                 }   
143                 
144                 return  $query['select'] . $query['from'] . $query['where']. $query['order_by'];
145                 
146     } // if
147     
148     function create_queue_items_query($order_by, $where,$filter=array(),$params=array(), $show_deleted = 0,$join_type='', $return_array = false,$parentbean=null, $singleSelect = false) {
149
150                 if ($return_array) {
151                         return parent::create_new_list_query($order_by, $where,$filter,$params, $show_deleted,$join_type, $return_array,$parentbean, $singleSelect); 
152                 }       
153
154                 if ( ( $this->db->dbType == 'mysql' ) or ( $this->db->dbType == 'oci8' ) )
155                 {
156
157                 $query = "SELECT $this->table_name.* ,
158                                         campaigns.name as campaign_name,
159                                         email_marketing.name as message_name,
160                                         (CASE related_type
161                                                 WHEN 'Contacts' THEN CONCAT(CONCAT(contacts.first_name, '&nbsp;' ), contacts.last_name)
162                                                 WHEN 'Leads' THEN CONCAT(CONCAT(leads.first_name, '&nbsp;' ), leads.last_name)
163                                                 WHEN 'Accounts' THEN accounts.name
164                                                 WHEN 'Users' THEN CONCAT(CONCAT(users.first_name, ' ' ), users.last_name)
165                                                 WHEN 'Prospects' THEN CONCAT(CONCAT(prospects.first_name, '&nbsp;' ), prospects.last_name)
166                                         END) recipient_name";
167                 }
168             if($this->db->dbType == 'mssql')
169                 {
170                                 $query = "SELECT $this->table_name.* ,
171                                         campaigns.name as campaign_name,
172                                         email_marketing.name as message_name,
173                                         (CASE related_type
174                                                 WHEN 'Contacts' THEN contacts.first_name + '&nbsp;' + contacts.last_name
175                                                 WHEN 'Leads' THEN  leads.first_name + '&nbsp;' + leads.last_name
176                                                 WHEN 'Accounts' THEN  accounts.name
177                                                 WHEN 'Users' THEN  users.first_name + ' ' + users.last_name                                             
178                                                 WHEN 'Prospects' THEN prospects.first_name + '&nbsp;' + prospects.last_name
179                                         END) recipient_name";
180                 }
181         
182                  $query .= " FROM $this->table_name
183                             LEFT JOIN users ON users.id = $this->table_name.related_id and $this->table_name.related_type ='Users'
184                                         LEFT JOIN contacts ON contacts.id = $this->table_name.related_id and $this->table_name.related_type ='Contacts'
185                                         LEFT JOIN leads ON leads.id = $this->table_name.related_id and $this->table_name.related_type ='Leads'
186                                         LEFT JOIN accounts ON accounts.id = $this->table_name.related_id and $this->table_name.related_type ='Accounts'
187                                         LEFT JOIN prospects ON prospects.id = $this->table_name.related_id and $this->table_name.related_type ='Prospects'
188                                         LEFT JOIN prospect_lists ON prospect_lists.id = $this->table_name.list_id 
189                     LEFT JOIN email_addr_bean_rel ON email_addr_bean_rel.bean_id = $this->table_name.related_id and $this->table_name.related_type = email_addr_bean_rel.bean_module and email_addr_bean_rel.deleted=0
190                                         LEFT JOIN campaigns ON campaigns.id = $this->table_name.campaign_id
191                                         LEFT JOIN email_marketing ON email_marketing.id = $this->table_name.marketing_id ";
192                  
193                  //B.F. #37943 
194                 if( isset($params['group_by']) )
195                 {
196                         $group_by = str_replace("emailman", "em", $params['group_by']);
197                     $query .= "INNER JOIN (select min(id) as id from emailman  em GROUP BY $group_by  ) secondary
198                                    on {$this->table_name}.id = secondary.id     ";
199                 }
200                 
201                 $where_auto = " $this->table_name.deleted=0";
202
203         if($where != "")
204                         $query .= "WHERE $where AND ".$where_auto;
205                 else
206                         $query .= "WHERE ".$where_auto;
207                         
208                 
209                 if($order_by != "")
210                         $query .= " ORDER BY $order_by";
211
212                 return $query;
213                 
214     }
215     
216         function create_list_query($order_by, $where, $show_deleted = 0){
217
218                 if ( ( $this->db->dbType == 'mysql' ) or ( $this->db->dbType == 'oci8' ) )
219                 {
220
221                 $query = "SELECT $this->table_name.* ,
222                                         campaigns.name as campaign_name,
223                                         email_marketing.name as message_name,
224                                         (CASE related_type
225                                                 WHEN 'Contacts' THEN CONCAT(CONCAT(contacts.first_name, '&nbsp;' ), contacts.last_name)
226                                                 WHEN 'Leads' THEN CONCAT(CONCAT(leads.first_name, '&nbsp;' ), leads.last_name)
227                                                 WHEN 'Accounts' THEN accounts.name
228                                                 WHEN 'Users' THEN CONCAT(CONCAT(users.first_name, ' ' ), users.last_name)
229                                                 WHEN 'Prospects' THEN CONCAT(CONCAT(prospects.first_name, '&nbsp;' ), prospects.last_name)
230                                         END) recipient_name";
231                 }
232             if($this->db->dbType == 'mssql')
233                 {
234                                 $query = "SELECT $this->table_name.* ,
235                                         campaigns.name as campaign_name,
236                                         email_marketing.name as message_name,
237                                         (CASE related_type
238                                                 WHEN 'Contacts' THEN contacts.first_name + '&nbsp;' + contacts.last_name
239                                                 WHEN 'Leads' THEN  leads.first_name + '&nbsp;' + leads.last_name
240                                                 WHEN 'Accounts' THEN  accounts.name
241                                                 WHEN 'Users' THEN  users.first_name + ' ' + users.last_name                                             
242                                                 WHEN 'Prospects' THEN prospects.first_name + '&nbsp;' + prospects.last_name
243                                         END) recipient_name";
244                 }
245
246                 $query .= "     FROM $this->table_name
247                                         LEFT JOIN users ON users.id = $this->table_name.related_id and $this->table_name.related_type ='Users'
248                                         LEFT JOIN contacts ON contacts.id = $this->table_name.related_id and $this->table_name.related_type ='Contacts'
249                                         LEFT JOIN leads ON leads.id = $this->table_name.related_id and $this->table_name.related_type ='Leads'
250                                         LEFT JOIN accounts ON accounts.id = $this->table_name.related_id and $this->table_name.related_type ='Accounts'
251                                         LEFT JOIN prospects ON prospects.id = $this->table_name.related_id and $this->table_name.related_type ='Prospects'
252                                         LEFT JOIN prospect_lists ON prospect_lists.id = $this->table_name.list_id 
253                     LEFT JOIN email_addr_bean_rel ON email_addr_bean_rel.bean_id = $this->table_name.related_id and $this->table_name.related_type = email_addr_bean_rel.bean_module and email_addr_bean_rel.deleted=0
254                                         LEFT JOIN campaigns ON campaigns.id = $this->table_name.campaign_id
255                                         LEFT JOIN email_marketing ON email_marketing.id = $this->table_name.marketing_id ";
256
257                 $where_auto = " $this->table_name.deleted=0";
258
259         if($where != "")
260                         $query .= "where $where AND ".$where_auto;
261                 else
262                         $query .= "where ".$where_auto;
263
264                 if($order_by != ""){
265                         $query .= " ORDER BY $order_by";
266                 }
267                 return $query;
268         }
269
270     function get_list_view_data()
271     {   global $locale, $current_user;
272         $temp_array = parent::get_list_view_array();
273
274             $query="select first_name, last_name from ". strtolower($temp_array['RELATED_TYPE']) ." where id ='".$temp_array['RELATED_ID']."'";
275                 
276         $result=$this->db->query($query);
277         $row=$this->db->fetchByAssoc($result);
278
279         if ($row) {
280             $full_name = $locale->getLocaleFormattedName($row['first_name'], $row['last_name'], '');
281             $temp_array['RECIPIENT_NAME']=$full_name;
282         }
283
284       //also store the recipient_email address
285         $query = "select addr.email_address from email_addresses addr,email_addr_bean_rel eb where eb.deleted=0 and addr.id=eb.email_address_id and bean_id ='". $temp_array['RELATED_ID']."' and primary_address = '1'";
286         
287         $result=$this->db->query($query);
288         $row=$this->db->fetchByAssoc($result);
289         if ($row) {
290             $temp_array['RECIPIENT_EMAIL']=$row['email_address'];
291         }
292         
293         $this->email1 = $temp_array['RECIPIENT_EMAIL'];
294                 $temp_array['EMAIL1_LINK'] = $current_user->getEmailLink('email1', $this, '', '', 'ListView');
295
296         return $temp_array;
297     }
298
299
300         function set_as_sent($email_address, $delete= true,$email_id=null, $email_type=null,$activity_type=null){
301
302                 global $timedate;
303
304                 $this->send_attempts++;
305                 if($delete || $this->send_attempts > 5){
306
307                         //create new campaign log record.
308                         
309                         $campaign_log = new CampaignLog();
310                         $campaign_log->campaign_id=$this->campaign_id;
311                         $campaign_log->target_tracker_key=$this->target_tracker_key;
312                         $campaign_log->target_id= $this->related_id;
313                         $campaign_log->target_type=$this->related_type;
314             $campaign_log->marketing_id=$this->marketing_id;
315                         //if test suppress duplicate email address checking.
316                         if (!$this->test) {
317                                 $campaign_log->more_information=$email_address;
318                         }
319                         $campaign_log->activity_type=$activity_type;
320                         $campaign_log->activity_date=$timedate->to_display_date_time(gmdate($GLOBALS['timedate']->get_db_date_time_format()));
321                         $campaign_log->list_id=$this->list_id;
322                         $campaign_log->related_id= $email_id;
323                         $campaign_log->related_type=$email_type;
324             $campaign_log->save();
325
326                         $query = "DELETE FROM emailman WHERE id = $this->id";
327                         $this->db->query($query);
328                 }else{
329                         //try to send the email again a day later.
330                         $query = 'UPDATE ' . $this->table_name . " SET in_queue='1', send_attempts='$this->send_attempts', in_queue_date='". gmdate($GLOBALS['timedate']->get_db_date_time_format()) ."' WHERE id = '$this->id'";
331                         $this->db->query($query);
332                 }
333         }
334
335     /**
336      * Function finds the reference email for the campaign. Since a campaign can have multiple email templates
337      * the reference email has same id as the marketing id.
338      * this function will create an email if one does not exist. also the function will load these relationships leads, accounts, contacts
339      * users and targets
340      *
341      * @param varchar marketing_id message id
342      * @param string $subject email subject
343      * @param string $body_text Email Body Text
344      * @param string $body_html Email Body HTML
345      * @param string $campaign_name Campaign Name
346      * @param string from_address Email address of the sender, usually email address of the configured inbox.
347      * @param string sender_id If of the user sending the campaign.
348      * @param array  macro_nv array of name value pair, one row for each replacable macro in email template text.
349      * @return
350      */
351     function create_ref_email($marketing_id,$subject,$body_text,$body_html,$campagin_name,$from_address,$sender_id,$notes,$macro_nv,$newmessage) {
352
353        global $mod_Strings;
354        $upd_ref_email=false;
355        if ($newmessage or empty($this->ref_email->id)) {
356            $this->ref_email = new Email();
357            $this->ref_email->retrieve($marketing_id, true, false);
358
359            //the reference email should be updated when user swithces from test mode to regular mode,and, for every run in test mode, and is user
360            //switches back to test mode.
361            //this is to account for changes to email template.
362            $upd_ref_email=(!empty($this->ref_email->id) and $this->ref_email->parent_type=='test' and $this->ref_email->parent_id=='test');
363           //following condition is for switching back to test mode.
364            if (!$upd_ref_email) $upd_ref_email=($this->test and !empty($this->ref_email->id) and empty($this->ref_email->parent_type) and empty($this->ref_email->parent_id));
365            if (empty($this->ref_email->id) or $upd_ref_email) {
366                 //create email record.
367                 $this->ref_email->id=$marketing_id;
368                 $this->ref_email->date_sent = '';
369
370                 if ($upd_ref_email==false) {
371                     $this->ref_email->new_with_id=true;
372                 }
373
374                 $this->ref_email->to_addrs= '';
375                 $this->ref_email->to_addrs_ids = '';
376                 $this->ref_email->to_addrs_names = '';
377                 $this->ref_email->to_addrs_emails ='';
378                 $this->ref_email->type= 'campaign';
379                 $this->ref_email->deleted = '0';
380                 $this->ref_email->name = $campagin_name.': '.$subject ;
381                 $this->ref_email->description_html = $body_html;
382                 $this->ref_email->description = $body_text;
383                 $this->ref_email->from_addr = $from_address;
384                 $this->ref_email->assigned_user_id = $sender_id;
385                 if ($this->test) {
386                     $this->ref_email->parent_type = 'test';
387                     $this->ref_email->parent_id =  'test';
388                 } else {
389                     $this->ref_email->parent_type = '';
390                     $this->ref_email->parent_id =  '';
391                 }
392                 $this->ref_email->date_start =$GLOBALS['timedate']->to_display_date(gmdate($GLOBALS['timedate']->dbDayFormat));
393                 $this->ref_email->time_start =$GLOBALS['timedate']->to_display_time(gmdate($GLOBALS['timedate']->dbTimeFormat));
394
395                 $this->ref_email->status='sent';
396                 $retId = $this->ref_email->save();
397
398                 if (count($notes) > 0 ) {
399                     if (!class_exists('Note')) 
400                     if (!class_exists('UploadFile')) require_once('include/upload_file.php');
401
402                 }
403
404                 foreach($notes as $note) {
405                     if($note->object_name == 'Note') {
406                         if (! empty($note->file->temp_file_location) && is_file($note->file->temp_file_location)) {
407                             $file_location = $note->file->temp_file_location;
408                             $filename = $note->file->original_file_name;
409                             $mime_type = $note->file->mime_type;
410                         } else {
411                             $file_location = rawurldecode(UploadFile::get_file_path($note->filename,$note->id));
412                             $filename = $note->id.$note->filename;
413                             $mime_type = $note->file_mime_type;
414                         }
415                     } elseif($note->object_name == 'DocumentRevision') { // from Documents
416                         $filename = $note->id.$note->filename;
417                         $file_location = getcwd().'/'.$GLOBALS['sugar_config']['upload_dir'].$filename;
418                         $mime_type = $note->file_mime_type;
419                     }
420
421                     $noteAudit = new Note();
422                     $noteAudit->parent_id = $retId;
423                     $noteAudit->parent_type = $this->ref_email->module_dir;
424                     $noteAudit->description = "[".$note->filename."] ".$mod_strings['LBL_ATTACHMENT_AUDIT'];
425                     $noteAudit->filename=$filename;
426                     $noteAudit->file_mime_type=$mime_type;
427                     $noteAudit_id=$noteAudit->save();
428
429                     UploadFile::duplicate_file($note->id, $noteAudit_id, $filename);
430                 }
431             }
432
433             //load relationships.
434             $this->ref_email->load_relationship('users');
435             $this->ref_email->load_relationship('prospects');
436             $this->ref_email->load_relationship('contacts');
437             $this->ref_email->load_relationship('leads');            
438             $this->ref_email->load_relationship('accounts');
439        }
440
441        if (!empty($this->related_id ) && !empty($this->related_type)) {
442
443             //save relationships.
444             switch ($this->related_type)  {
445                 case 'Users':
446                     $rel_name="users";
447                     break;
448
449                 case 'Prospects':
450                     $rel_name="prospects";
451                     break;
452
453                 case 'Contacts':
454                     $rel_name="contacts";
455                     break;
456
457                 case 'Leads':
458                     $rel_name="leads";
459                     break;                
460                     
461                 case 'Accounts':
462                     $rel_name="accounts";
463                     break;
464             }
465
466             //required for one email per campaign per marketing message.
467             $this->ref_email->$rel_name->add($this->related_id,array('campaign_data'=>serialize($macro_nv)));
468        }
469        return $this->ref_email->id;
470     }
471
472    /**
473     * The function creates a copy of email send to each target.
474     */
475     function create_indiv_email($module,$mail) {
476
477         global $locale;
478         $email = new Email();
479         $email->to_addrs= $module->name . '&lt;'.$module->email1.'&gt;';
480         $email->to_addrs_ids = $module->id .';';
481         $email->to_addrs_names = $module->name . ';';
482         $email->to_addrs_emails = $module->email1 . ';';
483         $email->type= 'archived';
484         $email->deleted = '0';
485         $email->name = $this->current_campaign->name.': '.$mail->Subject ;
486         if ($mail->ContentType == "text/plain") {
487             $email->description = $mail->Body;
488             $email->description_html =null;
489         } else {
490             $email->description_html = $mail->Body;
491             $email->description = $mail->AltBody;
492         }
493         $email->from_addr = $mail->From;
494         $email->assigned_user_id = $this->user_id;
495         $email->parent_type = $this->related_type;
496         $email->parent_id = $this->related_id ;
497
498         $email->date_start =date($GLOBALS['timedate']->dbDayFormat);
499         $email->time_start =date($GLOBALS['timedate']->dbTimeFormat);
500         $email->status='sent';
501         $retId = $email->save();
502
503         foreach($this->notes_array as $note) {
504             if(!class_exists('Note')) {
505                 
506             }
507             // create "audit" email without duping off the file to save on disk space
508             $noteAudit = new Note();
509             $noteAudit->parent_id = $retId;
510             $noteAudit->parent_type = $email->module_dir;
511             $noteAudit->description = "[".$note->filename."] ".$mod_strings['LBL_ATTACHMENT_AUDIT'];
512             $noteAudit->save();
513         }
514
515         if (!empty($this->related_id ) && !empty($this->related_type)) {
516
517                 //save relationships.
518                 switch ($this->related_type)  {
519                     case 'Users':
520                         $rel_name="users";
521                         break;
522
523                     case 'Prospects':
524                         $rel_name="prospects";
525                         break;
526
527                     case 'Contacts':
528                         $rel_name="contacts";
529                         break;
530
531                     case 'Leads':
532                         $rel_name="leads";
533                         break;
534                     
535                     case 'Accounts':
536                         $rel_name="accounts";
537                         break;
538                 }
539
540                 if (!empty($rel_name)) {
541                     $email->load_relationship($rel_name);
542                     $email->$rel_name->add($this->related_id);
543                 }
544         }
545         return $email->id;
546     }
547     /*
548      * Call this function to verify the email_marketing message and email_template configured 
549      * for the campaign. If issues are found a fatal error will be logged but processing will not stop.
550      * @return Boolean Returns true if all campaign parameters are set correctly
551      */
552     function verify_campaign($marketing_id) {
553
554         if (!isset($this->verified_email_marketing_ids[$marketing_id])) { 
555             if (!class_exists('EmailMarketing')) {
556                
557             }
558             $email_marketing = new EmailMarketing();
559             $ret=$email_marketing->retrieve($marketing_id);
560             if (empty($ret)) {
561                 $GLOBALS['log']->fatal('Error retrieving marketing message for the email campaign. marketing_id = ' .$marketing_id);
562                 return false;
563             }
564             
565             //verify the email template.
566             if (empty($email_marketing->template_id)) {
567                 $GLOBALS['log']->fatal('Error retrieving template for the email campaign. marketing_id = ' .$marketing_id);
568                 return false;
569             }
570             
571             if (!class_exists('EmailTemplate')) {
572                 
573             }
574             $emailtemplate= new EmailTemplate();
575                 
576             $ret=$emailtemplate->retrieve($email_marketing->template_id);
577             if (empty($ret)) {
578                 $GLOBALS['log']->fatal('Error retrieving template for the email campaign. template_id = ' .$email_marketing->template_id);
579                 return false;
580             }
581             
582             if (empty($emailtemplate->subject) and empty($emailtemplate->body) and empty($emailtemplate->body_html)) {
583                 $GLOBALS['log']->fatal('Email template is empty. email_template_id=' .$email_marketing->template_id);                
584                                 return false;
585             }
586             
587         }
588         $this->verified_email_marketing_ids[$marketing_id]=1;
589         
590         return true;
591     }
592         function sendEmail($mail,$save_emails=1,$testmode=false){
593             $this->test=$testmode;
594
595                 global $beanList, $beanFiles, $sugar_config;
596                 global $mod_strings;
597         global $locale;
598         $OBCharset = $locale->getPrecedentPreference('default_email_charset');
599                 $mod_strings = return_module_language( $sugar_config['default_language'], 'EmailMan');
600
601                 //get tracking entities locations.
602                 if (!isset($this->tracking_url)) {
603                         if (!class_exists('Administration')) {
604                                 
605                         }
606                         $admin=new Administration();
607                         $admin->retrieveSettings('massemailer'); //retrieve all admin settings.
608                     if (isset($admin->settings['massemailer_tracking_entities_location_type']) and $admin->settings['massemailer_tracking_entities_location_type']=='2'  and isset($admin->settings['massemailer_tracking_entities_location']) ) {
609                                 $this->tracking_url=$admin->settings['massemailer_tracking_entities_location'];
610                     } else {
611                                 $this->tracking_url=$sugar_config['site_url'];
612                     }
613                 }
614
615         //make sure tracking url ends with '/' character
616         $strLen = strlen($this->tracking_url);
617         if($this->tracking_url{$strLen-1} !='/'){
618             $this->tracking_url .='/';
619         }
620      
621                 if(!isset($beanList[$this->related_type])){
622                         return false;
623                 }
624                 $class = $beanList[$this->related_type];
625                 if (!class_exists($class)) {
626                         require_once($beanFiles[$class]);
627                 }
628
629                 if (!class_exists('Email')) {
630                         
631                 }
632
633                 $module = new $class();
634                 $module->retrieve($this->related_id);
635                 $module->emailAddress->handleLegacyRetrieve($module);
636
637         //check to see if bean has a primary email address
638         if (!$this->is_primary_email_address($module)) {
639             //no primary email address designated, do not send out email, create campaign log
640             //of type send error to denote that this user was not emailed
641             $this->set_as_sent($module->email1, true,null,null,'send error');
642             //create fatal logging for easy review of cause.
643             $GLOBALS['log']->fatal('Email Address provided is not Primary Address for email with id ' . $module->email1 . "' Emailman id=$this->id");
644             return true;
645         }
646
647                 if (!$this->valid_email_address($module->email1)) {
648                         $this->set_as_sent($module->email1, true,null,null,'invalid email');
649                         $GLOBALS['log']->fatal('Encountered invalid email address' . $module->email1 . " Emailman id=$this->id");
650                         return true;
651                 }
652         
653         if ((!isset($module->email_opt_out) 
654                     || ($module->email_opt_out !== 'on' 
655                         && $module->email_opt_out !== 1 
656                         && $module->email_opt_out !== '1')) 
657             && (!isset($module->invalid_email) 
658                     || ($module->invalid_email !== 'on' 
659                         && $module->invalid_email !== 1 
660                         && $module->invalid_email !== '1'))){
661             $lower_email_address=strtolower($module->email1);
662                         //test against indivdual address.
663                         if (isset($this->restricted_addresses) and isset($this->restricted_addresses[$lower_email_address])) {
664                                 $this->set_as_sent($lower_email_address, true,null,null,'blocked');
665                                 return true;
666                         }
667                         //test against restricted domains
668                         $at_pos=strrpos($lower_email_address,'@');
669                         if ($at_pos !== false) {
670                                 foreach ($this->restricted_domains as $domain=>$value) {
671                                         $pos=strrpos($lower_email_address,$domain);
672                                         if ($pos !== false && $pos > $at_pos) {
673                                                 //found
674                                                 $this->set_as_sent($lower_email_address, true,null,null,'blocked');
675                                                 return true;
676                                         }
677                                 }
678                         }
679
680                         //test for duplicate email address by marketing id.
681             $dup_query="select id from campaign_log where more_information='".$module->email1."' and marketing_id='".$this->marketing_id."'";
682                         $dup=$this->db->query($dup_query);
683                         $dup_row=$this->db->fetchByAssoc($dup);
684                         if (!empty($dup_row)) {
685                                 //we have seen this email address before
686                                 $this->set_as_sent($module->email1,true,null,null,'blocked');
687                                 return true;
688                         }
689
690                         $this->target_tracker_key=create_guid();
691
692                         //fetch email marketing.
693                         if (empty($this->current_emailmarketing) or !isset($this->current_emailmarketing)) {
694                                 if (!class_exists('EmailMarketing')) {
695                                         
696                                 }
697
698                                 $this->current_emailmarketing=new EmailMarketing();
699
700                         }
701                         if (empty($this->current_emailmarketing->id) or $this->current_emailmarketing->id !== $this->marketing_id) {
702                                 $this->current_emailmarketing->retrieve($this->marketing_id);
703
704                 $this->newmessage = true;
705                         }
706                         //fetch email template associate with the marketing message.
707                         if (empty($this->current_emailtemplate) or $this->current_emailtemplate->id !== $this->current_emailmarketing->template_id) {
708                                 if (!class_exists('EmailTemplate')) {
709                                         
710                                 }
711                                 $this->current_emailtemplate= new EmailTemplate();
712
713                                 $this->current_emailtemplate->retrieve($this->current_emailmarketing->template_id);
714
715                                 //escape email template contents.
716                                 $this->current_emailtemplate->subject=from_html($this->current_emailtemplate->subject);
717                                 $this->current_emailtemplate->body_html=from_html($this->current_emailtemplate->body_html);
718                                 $this->current_emailtemplate->body=from_html($this->current_emailtemplate->body);
719
720                                 $q = "SELECT * FROM notes WHERE parent_id = '".$this->current_emailtemplate->id."' AND deleted = 0";
721                                 $r = $this->db->query($q);
722
723                                 // cn: bug 4684 - initialize the notes array, else old data is still around for the next round
724                                 $this->notes_array = array();
725                 if (!class_exists('Note')){
726                         require_once('modules/Notes/Note.php');
727                                 } 
728                                 while($a = $this->db->fetchByAssoc($r)) {
729                                         $noteTemplate = new Note();
730                                         $noteTemplate->retrieve($a['id']);
731                                         $this->notes_array[] = $noteTemplate;
732                                 }
733                         }
734
735                         // fetch mailbox details..
736                         if(empty($this->current_mailbox)) {
737                                 if (!class_exists('InboundEmail')) {
738                                         
739                                 }
740                                 $this->current_mailbox= new InboundEmail();
741                         }
742                         if (empty($this->current_mailbox->id) or $this->current_mailbox->id !== $this->current_emailmarketing->inbound_email_id) {
743                                 $this->current_mailbox->retrieve($this->current_emailmarketing->inbound_email_id);
744                                 //extract the email address.
745                                 $this->mailbox_from_addr=$this->current_mailbox->get_stored_options('from_addr','nobody@example.com',null);
746                         }
747
748                         // fetch campaign details..
749                         if (empty($this->current_campaign)) {
750                                 if (!class_exists('Campaign')) {
751                                         
752                                 }
753                                 $this->current_campaign= new Campaign();
754                         }
755                         if (empty($this->current_campaign->id) or $this->current_campaign->id !== $this->current_emailmarketing->campaign_id) {
756                                 $this->current_campaign->retrieve($this->current_emailmarketing->campaign_id);
757
758                                 //load defined tracked_urls
759                                 $this->current_campaign->load_relationship('tracked_urls');
760                                 $query_array=$this->current_campaign->tracked_urls->getQuery(true);
761                                 $query_array['select']="SELECT tracker_name, tracker_key, id, is_optout ";
762                                 $result=$this->current_campaign->db->query(implode(' ',$query_array));
763
764                                 $this->has_optout_links=false;
765                                 $this->tracker_urls=array();
766                                 while (($row=$this->current_campaign->db->fetchByAssoc($result)) != null) {
767                                         $this->tracker_urls['{'.$row['tracker_name'].'}']=$row;
768                                         //has the user defined opt-out links for the campaign.
769                                         if ($row['is_optout']==1) {
770                                                 $this->has_optout_links=true;
771                                         }
772                                 }
773                         }
774
775                         $mail->ClearAllRecipients();
776                         $mail->ClearReplyTos();
777                         $mail->Sender   = $this->mailbox_from_addr;
778                         $mail->From     = $this->mailbox_from_addr;
779                         $mail->FromName = $this->current_emailmarketing->from_name;
780                         $mail->ClearCustomHeaders();
781             $mail->AddCustomHeader('X-CampTrackID:'.$this->target_tracker_key);
782             //CL - Bug 25256 Check if we have a reply_to_name/reply_to_addr value from the email marketing table.  If so use email marketing entry; otherwise current mailbox (inbound email) entry
783                         $replyToName = empty($this->current_emailmarketing->reply_to_name) ? $this->current_mailbox->get_stored_options('reply_to_name',$mail->FromName,null) : $this->current_emailmarketing->reply_to_name;
784                         $replyToAddr = empty($this->current_emailmarketing->reply_to_addr) ? $this->current_mailbox->get_stored_options('reply_to_addr',$mail->From,null) : $this->current_emailmarketing->reply_to_addr;          
785
786                         $mail->AddReplyTo($replyToAddr,$locale->translateCharsetMIME(trim($replyToName), 'UTF-8', $OBCharset));
787
788                         //parse and replace bean variables.
789             $macro_nv=array();
790                         $template_data=  $this->current_emailtemplate->parse_email_template(array('subject'=>$this->current_emailtemplate->subject,
791                                                                                                                                                                           'body_html'=>$this->current_emailtemplate->body_html,
792                                                                                                                                                                           'body'=>$this->current_emailtemplate->body,
793                                                                                                                                                                           )
794                                                                                                                                                                           ,'Contacts', $module
795                                                                                       ,$macro_nv);
796
797             //add email address to this list.
798             $macro_nv['sugar_to_email_address']=$module->email1;
799             $macro_nv['email_template_id']=$this->current_emailmarketing->template_id;
800
801             //parse and replace urls.
802                         //this is new style of adding tracked urls to a campaign.
803                         $tracker_url_template= $this->tracking_url . 'index.php?entryPoint=campaign_trackerv2&track=%s'.'&identifier='.$this->target_tracker_key;
804                         $removeme_url_template=$this->tracking_url . 'index.php?entryPoint=removeme&identifier='.$this->target_tracker_key;
805                         $template_data=  $this->current_emailtemplate->parse_tracker_urls($template_data,$tracker_url_template,$this->tracker_urls,$removeme_url_template);
806                         $mail->AddAddress($module->email1,$locale->translateCharsetMIME(trim($module->name), 'UTF-8', $OBCharset) );
807
808             //refetch strings in case they have been changed by creation of email templates or other beans.
809             $mod_strings = return_module_language( $sugar_config['default_language'], 'EmailMan');
810
811             if($this->test){
812                 $mail->Subject =  $mod_strings['LBL_PREPEND_TEST'] . $template_data['subject'];
813             }else{
814                 $mail->Subject =  $template_data['subject'];
815             }
816
817             //check if this template is meant to be used as "text only"
818             $text_only = false;
819             if(isset($this->current_emailtemplate->text_only) && $this->current_emailtemplate->text_only){$text_only =true;}
820             //if this template is textonly, then just send text body.  Do not add tracker, opt out,
821             //or perform other processing as it will not show up in text only email
822             if($text_only){
823                 $this->description_html = '';
824                 $mail->IsHTML(false);
825                 $mail->Body = $template_data['body'];
826
827             }else{
828                 $mail->Body = wordwrap($template_data['body_html'], 900);
829                 //BEGIN:this code will trigger for only campaigns pending before upgrade to 4.2.0.
830                 //will be removed for the next release.
831                 if(!isset($btracker)) $btracker=false;
832                 if ($btracker) {
833                     $mail->Body .= "<br><br><a href='". $tracker_url ."'>" . $tracker_text . "</a><br><br>";
834                 } else {
835                     if (!empty($tracker_url)) {
836                         $mail->Body = str_replace('TRACKER_URL_START', "<a href='" . $tracker_url ."'>", $mail->Body);
837                         $mail->Body = str_replace('TRACKER_URL_END', "</a>", $mail->Body);
838                         $mail->AltBody = str_replace('TRACKER_URL_START', "<a href='" . $tracker_url ."'>", $mail->AltBody);
839                         $mail->AltBody = str_replace('TRACKER_URL_END', "</a>", $mail->AltBody);
840                     }
841                 }
842                 //END
843
844                 //do not add the default remove me link if the campaign has a trackerurl of the opotout link
845                 if ($this->has_optout_links==false) {
846                     $mail->Body .= "<br><font size='2'>{$mod_strings['TXT_REMOVE_ME']}<a href='". $this->tracking_url . "index.php?entryPoint=removeme&identifier={$this->target_tracker_key}'>{$mod_strings['TXT_REMOVE_ME_CLICK']}</a></font>";
847                 }
848                 // cn: bug 11979 - adding single quote to comform with HTML email RFC
849                 $mail->Body .= "<br><IMG HEIGHT='1' WIDTH='1' src='{$this->tracking_url}index.php?entryPoint=image&identifier={$this->target_tracker_key}'>";
850
851                 $mail->AltBody = $template_data['body'];
852                 if ($btracker) {
853                     $mail->AltBody .="\n". $tracker_url;
854                 }
855                 if ($this->has_optout_links==false) {
856                     $mail->AltBody .="\n\n\n{$mod_strings['TXT_REMOVE_ME_ALT']} ". $this->tracking_url . "index.php?entryPoint=removeme&identifier=$this->target_tracker_key";
857                 }
858
859             }
860
861                         // cn: bug 4684, handle attachments in email templates.
862                         $mail->handleAttachments($this->notes_array);
863                         $tmp_Subject = $mail->Subject;
864                         $mail->prepForOutbound();
865
866                 $success = $mail->Send();
867                 //Do not save the encoded subject.
868             $mail->Subject = $tmp_Subject;
869                         if($success ){
870                 $email_id=null;
871                 if ($save_emails==1) {
872                     $email_id=$this->create_indiv_email($module,$mail);
873                 } else {
874                     //find/create reference email record. all campaign targets reveiving this message will be linked with this message.
875                     $email_id=$this->create_ref_email($this->marketing_id,
876                                             $this->current_emailtemplate->subject,
877                                             $this->current_emailtemplate->body,
878                                             $this->current_emailtemplate->body_html,
879                                             $this->current_campaign->name,
880                                             $this->mailbox_from_addr,
881                                             $this->user_id,
882                                             $this->notes_array,
883                                             $macro_nv,
884                                             $this->newmessage
885                      );
886                     $this->newmessage = false;
887                 }
888             }
889
890                         if ($success) {
891                                 $this->set_as_sent($module->email1, true, $email_id, 'Emails', 'targeted');
892                         } else {
893
894                                 if(!empty($layout_def['parent_id'])) {
895                         if (isset($layout_def['fields'][strtoupper($layout_def['parent_id'])])) {
896                             $parent.="&parent_id=".$layout_def['fields'][strtoupper($layout_def['parent_id'])];
897                         }
898                     }
899                     if(!empty($layout_def['parent_module'])) {
900                         if (isset($layout_def['fields'][strtoupper($layout_def['parent_module'])])) {
901                             $parent.="&parent_module=".$layout_def['fields'][strtoupper($layout_def['parent_module'])];
902                         }
903                     }
904                                 //log send error. save for next attempt after 24hrs. no campaign log entry will be created.
905                                 $this->set_as_sent($module->email1,false,null,null,'send error');
906                         }
907                 }else{
908             $success = false;
909             $this->target_tracker_key=create_guid();
910
911                         if (isset($module->email_opt_out) && ($module->email_opt_out === 'on' || $module->email_opt_out == '1' || $module->email_opt_out == 1)) {
912                                 $this->set_as_sent($module->email1,true,null,null,'removed');
913                         } else {
914                                 if (isset($module->invalid_email) && ($module->invalid_email == 1 || $module->invalid_email == '1')) {
915                                         $this->set_as_sent($module->email1,true,null,null,'invalid email');
916                                 } else {
917                                         $this->set_as_sent($module->email1,true, null,null,'send error');
918                                 }
919                         }
920                 }
921
922                 return $success;
923         }
924
925         /*
926          * Validates the passed email address.
927          * Limitations of this algorithm: does not validate email addressess that end with .meuseum
928          *
929          */
930         function valid_email_address($email_address) {
931
932                 $email_address=trim($email_address);
933                 if (empty($email_address)) {
934                         return false;
935                 }
936
937                 $pattern='/[A-Z0-9\._%-]+@[A-Z0-9\.-]+\.[A-Za-z]{2,}$/i';
938                 $ret=preg_match($pattern, $email_address);
939                 echo $ret;
940                 if ($ret===false or $ret==0) {
941                         return false;
942                 }
943                 return true;
944         }
945     
946     /*
947      * This function takes in the given bean and searches for a related email address 
948      * that has been designated as primary.  If one is found, true is returned
949      * If no primary email address is found, then false is returned
950      * 
951      */
952     function is_primary_email_address($bean){    
953         $email_address=trim($bean->email1);
954
955         if (empty($email_address)) {
956             return false;
957         }
958         //query for this email address rel and see if this is primary address
959         $primary_qry = "select email_address_id from email_addr_bean_rel where bean_id = '".$bean->id."' and email_addr_bean_rel.primary_address=1 and deleted=0";
960         $res = $bean->db->query($primary_qry);      
961         $prim_row=$this->db->fetchByAssoc($res);
962         //return true if this is primary
963         if (!empty($prim_row)) {
964             return true;
965         }  
966         return false;
967      
968      }
969      
970     function create_export_query(&$order_by, &$where) {
971         $custom_join = $this->custom_fields->getJOIN(true, true,$where);
972         $query = "SELECT emailman.*";
973         if($custom_join){
974             $query .= $custom_join['select'];
975         }
976         
977         $query .= " FROM emailman ";
978         
979         if($custom_join){
980             $query .= $custom_join['join'];
981         }
982
983         $where_auto = "( emailman.deleted IS NULL OR emailman.deleted=0 )";
984
985         if($where != "")
986             $query .= "where ($where) AND ".$where_auto;
987         else
988             $query .= "where ".$where_auto;
989
990         if(!empty($order_by))
991             $query .=  " ORDER BY ". $this->process_order_by($order_by, null);
992
993         return $query;
994     }
995 }
996 ?>