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