]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - include/OutboundEmail/OutboundEmail.php
Release 6.4.0
[Github/sugarcrm.git] / include / OutboundEmail / OutboundEmail.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  * Outbuound email management
40  * @api
41  */
42 class OutboundEmail {
43         /**
44          * Necessary
45          */
46         var $db;
47         var $field_defs = array(
48                 'id',
49                 'name',
50                 'type',
51                 'user_id',
52                 'mail_sendtype',
53                 'mail_smtptype',
54                 'mail_smtpserver',
55                 'mail_smtpport',
56                 'mail_smtpuser',
57                 'mail_smtppass',
58                 'mail_smtpauth_req',
59                 'mail_smtpssl',
60         );
61
62         /**
63          * Columns
64          */
65         var $id;
66         var $name;
67         var $type; // user or system
68         var $user_id; // owner
69         var $mail_sendtype; // smtp
70         var $mail_smtptype;
71         var $mail_smtpserver;
72         var $mail_smtpport = 25;
73         var $mail_smtpuser;
74         var $mail_smtppass;
75         var $mail_smtpauth_req; // bool
76         var $mail_smtpssl; // bool
77         var $mail_smtpdisplay; // calculated value, not in DB
78         var $new_with_id = FALSE;
79
80         /**
81          * Sole constructor
82          */
83         function OutboundEmail() {
84                 $this->db = DBManagerFactory::getInstance();
85         }
86
87         /**
88          * Retrieves the mailer for a user if they have overriden the username
89          * and password for the default system account.
90          *
91          * @param String $user_id
92          */
93         function getUsersMailerForSystemOverride($user_id)
94         {
95             $query = "SELECT id FROM outbound_email WHERE user_id = '{$user_id}' AND type = 'system-override' ORDER BY name";
96                 $rs = $this->db->query($query);
97                 $row = $this->db->fetchByAssoc($rs);
98                 if(!empty($row['id']))
99                 {
100                   $oe = new OutboundEmail();
101                   $oe->retrieve($row['id']);
102                   return $oe;
103                 }
104                 else
105                   return null;
106         }
107
108         /**
109          * Duplicate the system account for a user, setting new parameters specific to the user.
110          *
111          * @param string $user_id
112          * @param string $user_name
113          * @param string $user_pass
114          */
115         function createUserSystemOverrideAccount($user_id,$user_name = "",$user_pass = "")
116         {
117             $ob = $this->getSystemMailerSettings();
118             $ob->id = create_guid();
119             $ob->new_with_id = TRUE;
120             $ob->user_id = $user_id;
121             $ob->type = 'system-override';
122             $ob->mail_smtpuser = $user_name;
123             $ob->mail_smtppass = $user_pass;
124             $ob->save();
125
126             return $ob;
127         }
128
129         /**
130          * Determines if a user needs to set their user name/password for their system
131          * override account.
132          *
133          * @param unknown_type $user_id
134          * @return unknown
135          */
136         function doesUserOverrideAccountRequireCredentials($user_id)
137         {
138             $userCredentialsReq = FALSE;
139             $sys = new OutboundEmail();
140             $ob = $sys->getSystemMailerSettings(); //Dirties '$this'
141
142             //If auth for system account is disabled or user can use system outbound account return false.
143             if($ob->mail_smtpauth_req == 0 || $this->isAllowUserAccessToSystemDefaultOutbound() || $this->mail_sendtype == 'sendmail')
144                return $userCredentialsReq;
145
146             $userOverideAccount = $this->getUsersMailerForSystemOverride($user_id);
147             if( $userOverideAccount == null || empty($userOverideAccount->mail_smtpuser) || empty($userOverideAccount->mail_smtpuser) )
148                $userCredentialsReq = TRUE;
149
150         return $userCredentialsReq;
151
152         }
153
154         /**
155          * Retrieves name value pairs for opts lists
156          */
157         function getUserMailers($user) {
158                 global $app_strings;
159
160                 $q = "SELECT * FROM outbound_email WHERE user_id = '{$user->id}' AND type = 'user' ORDER BY name";
161                 $r = $this->db->query($q);
162
163                 $ret = array();
164
165                 $system = $this->getSystemMailerSettings();
166
167                 //Now add the system default or user override default to the response.
168                 if(!empty($system->id) )
169                 {
170                         if ($system->mail_sendtype == 'SMTP')
171                         {
172                             $systemErrors = "";
173                 $userSystemOverride = $this->getUsersMailerForSystemOverride($user->id);
174
175                 //If the user is required to to provide a username and password but they have not done so yet,
176                     //create the account for them.
177                      $autoCreateUserSystemOverride = FALSE;
178                          if( $this->doesUserOverrideAccountRequireCredentials($user->id) )
179                          {
180                               $systemErrors = $app_strings['LBL_EMAIL_WARNING_MISSING_USER_CREDS'];
181                               $autoCreateUserSystemOverride = TRUE;
182                          }
183
184                 //Substitute in the users system override if its available.
185                 if($userSystemOverride != null)
186                            $system = $userSystemOverride;
187                         else if ($autoCreateUserSystemOverride)
188                        $system = $this->createUserSystemOverrideAccount($user->id,"","");
189
190                             $isEditable = ($system->type == 'system') ? FALSE : TRUE; //User overrides can be edited.
191
192                 if( !empty($system->mail_smtpserver) )
193                                     $ret[] = array('id' =>$system->id, 'name' => "$system->name", 'mail_smtpserver' => $system->mail_smtpdisplay,
194                                                                    'is_editable' => $isEditable, 'type' => $system->type, 'errors' => $systemErrors);
195                         }
196                         else //Sendmail
197                         {
198                                 $ret[] = array('id' =>$system->id, 'name' => "{$system->name} - sendmail", 'mail_smtpserver' => 'sendmail',
199                                                                 'is_editable' => false, 'type' => $system->type, 'errors' => '');
200                         }
201                 }
202
203                 while($a = $this->db->fetchByAssoc($r))
204                 {
205                         $oe = array();
206                         if($a['mail_sendtype'] != 'SMTP')
207                                 continue;
208
209                         $oe['id'] =$a['id'];
210                         $oe['name'] = $a['name'];
211                         $oe['type'] = $a['type'];
212                         $oe['is_editable'] = true;
213                         $oe['errors'] = '';
214                         if ( !empty($a['mail_smtptype']) )
215                             $oe['mail_smtpserver'] = $this->_getOutboundServerDisplay($a['mail_smtptype'],$a['mail_smtpserver']);
216                         else
217                             $oe['mail_smtpserver'] = $a['mail_smtpserver'];
218
219                         $ret[] = $oe;
220                 }
221
222                 return $ret;
223         }
224
225         /**
226          * Retrieves a cascading mailer set
227          * @param object user
228          * @param string mailer_id
229          * @return object
230          */
231         function getUserMailerSettings(&$user, $mailer_id='', $ieId='') {
232                 $mailer = '';
233
234                 if(!empty($mailer_id)) {
235                         $mailer = "AND id = '{$mailer_id}'";
236                 } elseif(!empty($ieId)) {
237                         $q = "SELECT stored_options FROM inbound_email WHERE id = '{$ieId}'";
238                         $r = $this->db->query($q);
239                         $a = $this->db->fetchByAssoc($r);
240
241                         if(!empty($a)) {
242                                 $opts = unserialize(base64_decode($a['stored_options']));
243
244                                 if(isset($opts['outbound_email'])) {
245                                         $mailer = "AND id = '{$opts['outbound_email']}'";
246                                 }
247                         }
248                 }
249
250                 $q = "SELECT id FROM outbound_email WHERE user_id = '{$user->id}' {$mailer}";
251                 $r = $this->db->query($q);
252                 $a = $this->db->fetchByAssoc($r);
253
254                 if(empty($a)) {
255                         $ret = $this->getSystemMailerSettings();
256                 } else {
257                         $ret = $this->retrieve($a['id']);
258                 }
259                 return $ret;
260         }
261
262         /**
263          * Retrieve an array containing inbound emails ids for all inbound email accounts which have
264          * their outbound account set to this object.
265          *
266          * @param SugarBean $user
267          * @param string $outbound_id
268          * @return array
269          */
270         function getAssociatedInboundAccounts($user)
271         {
272             $query = "SELECT id,stored_options FROM inbound_email WHERE is_personal='1' AND deleted='0' AND created_by = '{$user->id}'";
273                 $rs = $this->db->query($query);
274
275         $results = array();
276         while($row = $this->db->fetchByAssoc($rs) )
277         {
278             $opts = unserialize(base64_decode($row['stored_options']));
279             if( isset($opts['outbound_email']) && $opts['outbound_email'] == $this->id)
280             {
281                 $results[] = $row['id'];
282             }
283                 }
284
285                 return $results;
286         }
287         /**
288          * Retrieves a cascading mailer set
289          * @param object user
290          * @param string mailer_id
291          * @return object
292          */
293         function getInboundMailerSettings($user, $mailer_id='', $ieId='') {
294                 $mailer = '';
295
296                 if(!empty($mailer_id)) {
297                         $mailer = "id = '{$mailer_id}'";
298                 } elseif(!empty($ieId)) {
299                         $q = "SELECT stored_options FROM inbound_email WHERE id = '{$ieId}'";
300                         $r = $this->db->query($q);
301                         $a = $this->db->fetchByAssoc($r);
302
303                         if(!empty($a)) {
304                                 $opts = unserialize(base64_decode($a['stored_options']));
305
306                                 if(isset($opts['outbound_email'])) {
307                                         $mailer = "id = '{$opts['outbound_email']}'";
308                                 } else {
309                                         $mailer = "id = '{$ieId}'";
310                                 }
311                         } else {
312                                 // its possible that its an system account
313                                 $mailer = "id = '{$ieId}'";
314                         }
315                 }
316
317                 if (empty($mailer)) {
318                         $mailer = "type = 'system'";
319                 } // if
320
321                 $q = "SELECT id FROM outbound_email WHERE {$mailer}";
322                 $r = $this->db->query($q);
323                 $a = $this->db->fetchByAssoc($r);
324
325                 if(empty($a)) {
326                         $ret = $this->getSystemMailerSettings();
327                 } else {
328                         $ret = $this->retrieve($a['id']);
329                 }
330                 return $ret;
331         }
332
333         /**
334          *  Determine if the user is alloweed to use the current system outbound connection.
335          */
336         function isAllowUserAccessToSystemDefaultOutbound()
337         {
338             $allowAccess = FALSE;
339
340             // first check that a system default exists
341             $q = "SELECT id FROM outbound_email WHERE type = 'system'";
342                 $r = $this->db->query($q);
343                 $a = $this->db->fetchByAssoc($r);
344                 if (!empty($a)) {
345                     // next see if the admin preference for using the system outbound is set
346             $admin = new Administration();
347             $admin->retrieveSettings('',TRUE);
348             if (isset($admin->settings['notify_allow_default_outbound'])
349                 &&  $admin->settings['notify_allow_default_outbound'] == 2 )
350                 $allowAccess = TRUE;
351         }
352
353         return $allowAccess;
354         }
355
356         /**
357          * Retrieves the system's Outbound options
358          */
359         function getSystemMailerSettings() {
360                 $q = "SELECT id FROM outbound_email WHERE type = 'system'";
361                 $r = $this->db->query($q);
362                 $a = $this->db->fetchByAssoc($r);
363
364                 if(empty($a)) {
365                         $this->id = "";
366                         $this->name = 'system';
367                         $this->type = 'system';
368                         $this->user_id = '1';
369                         $this->mail_sendtype = 'SMTP';
370                         $this->mail_smtptype = 'other';
371                         $this->mail_smtpserver = '';
372                         $this->mail_smtpport = 25;
373                         $this->mail_smtpuser = '';
374                         $this->mail_smtppass = '';
375                         $this->mail_smtpauth_req = 1;
376                         $this->mail_smtpssl = 0;
377                         $this->mail_smtpdisplay = $this->_getOutboundServerDisplay($this->mail_smtptype,$this->mail_smtpserver);
378                         $this->save();
379                         $ret = $this;
380                 } else {
381                         $ret = $this->retrieve($a['id']);
382                 }
383
384                 return $ret;
385         }
386
387         /**
388          * Populates this instance
389          * @param string $id
390          * @return object $this
391          */
392         function retrieve($id) {
393                 require_once('include/utils/encryption_utils.php');
394                 $q = "SELECT * FROM outbound_email WHERE id = '{$id}'";
395                 $r = $this->db->query($q);
396                 $a = $this->db->fetchByAssoc($r);
397
398                 if(!empty($a)) {
399                         foreach($a as $k => $v) {
400                                 if ($k == 'mail_smtppass' && !empty($v)) {
401                                         $this->$k = blowfishDecode(blowfishGetKey('OutBoundEmail'), $v);
402                                 } else {
403                                         $this->$k = $v;
404                                 } // else
405                         }
406                         if ( !empty($a['mail_smtptype']) )
407                             $this->mail_smtpdisplay = $this->_getOutboundServerDisplay($a['mail_smtptype'],$a['mail_smtpserver']);
408                         else
409                             $this->mail_smtpdisplay = $a['mail_smtpserver'];
410                 }
411
412                 return $this;
413         }
414
415         function populateFromPost() {
416                 foreach($this->field_defs as $def) {
417                         if(isset($_POST[$def])) {
418                                 $this->$def = $_POST[$def];
419                         } else {
420                                 $this->$def = "";
421                         }
422                 }
423         }
424
425         /**
426          * saves an instance
427          */
428         function save() {
429                 require_once('include/utils/encryption_utils.php');
430                 if(empty($this->id) || $this->new_with_id) {
431
432                     if( empty($this->id) )
433                             $this->id = create_guid();
434
435                         $cols = '';
436                         $values = '';
437
438                         foreach($this->field_defs as $def) {
439                             if(!empty($cols)) {
440                                         $cols .= ", ";
441                                 }
442                                 if(!empty($values)) {
443                                         $values .= ", ";
444                                 }
445                                 $cols .= $def;
446                                 $pattern = '\\';
447                                 if ($def == 'mail_smtppass' && !empty($this->$def)) {
448                                         $this->$def = blowfishEncode(blowfishGetKey('OutBoundEmail'), $this->$def);
449                                 } // if
450                                 if($def == 'mail_smtpauth_req' || $def == 'mail_smtpssl'){
451                                         if(empty($this->$def)){
452                                                 $this->$def = 0;
453                                         }
454                                         $values .= $this->$def;
455                                 }elseif($def == 'mail_smtpuser' && strpos($this->$def, '\\' )){ //bug 41766: taking care of '\' in username
456                                         $temp = explode('\\', $this->$def);
457                                         $this->$def = $temp[0] . '\\\\' .$temp[1];
458                                         $values .= "{$def} = '{$this->$def}'";
459                                 }else{
460                                         $values .= "'{$this->$def}'";
461                                 }
462
463
464                         }
465
466                         $q  = "INSERT INTO outbound_email ($cols) VALUES ({$values})";
467                 } else {
468                         $values = array();
469                         foreach($this->field_defs as $def) {
470                                 switch($def) {
471                                         case 'mail_smtpport':
472                                         case 'mail_smtpauth_req':
473                                         case 'mail_smtpssl':
474                                                 if(empty($this->$def)){
475                                                         $this->$def = 0;
476                                                 }
477                         $values []= "{$def} = {$this->$def}";
478                                                 break;
479                                         case 'mail_smtppass':
480                                                 if(!empty($this->mail_smtppass)) {
481                                                         $this->mail_smtppass = blowfishEncode(blowfishGetKey('OutBoundEmail'), $this->mail_smtppass);
482                                                 } else {
483                                                         // ignore empty password unless username is empty too
484                                                         if(!empty($this->mail_smtpuser)) {
485                                 continue;
486                                                         }
487                                                 }
488                         $values []= "{$def} = '{$this->$def}'";
489                                                 break;
490                                         case 'mail_smtpuser':
491                                                 if(strpos($this->$def, '\\' )){ //bug 41766: taking care of '\' in username
492                                                         $temp = explode('\\', $this->$def);
493                                                         $this->$def = $temp[0] . '\\\\' .$temp[1];
494                                                 }
495                                         default:
496                         $values []= "{$def} = '{$this->$def}'";
497                                 }
498                         }
499                         $q = "UPDATE outbound_email SET ".implode(', ', $values)." WHERE id = '{$this->id}'";
500                 }
501
502                 $this->db->query($q, true);
503                 return $this;
504         }
505
506         /**
507          * Saves system mailer.  Presumes all values are filled.
508          */
509         function saveSystem() {
510                 $q = "SELECT id FROM outbound_email WHERE type = 'system'";
511                 $r = $this->db->query($q);
512                 $a = $this->db->fetchByAssoc($r);
513
514                 if(empty($a)) {
515                         $a['id'] = ''; // trigger insert
516                 }
517
518                 $this->id = $a['id'];
519                 $this->name = 'system';
520                 $this->type = 'system';
521                 $this->user_id = '1';
522                 $this->save();
523
524                 $this->updateUserSystemOverrideAccounts();
525
526         }
527
528         /**
529          * Update the user system override accounts with the system information if anything has changed.
530          *
531          */
532         function updateUserSystemOverrideAccounts()
533         {
534             $updateFields = array('mail_smtptype','mail_sendtype','mail_smtpserver', 'mail_smtpport','mail_smtpauth_req','mail_smtpssl');
535
536             //Update the username ans password for the override accounts if alloweed access.
537             if( $this->isAllowUserAccessToSystemDefaultOutbound() )
538             {
539                 $updateFields[] = 'mail_smtpuser';
540                 $updateFields[] = 'mail_smtppass';
541             }
542
543             $values = "";
544             foreach ($updateFields as $singleField)
545             {
546                 if(!empty($values))
547                                         $values .= ", ";
548                 if($singleField == 'mail_smtpauth_req' || $singleField == 'mail_smtpssl')
549                 {
550                                 if(empty($this->$singleField))
551                                     $this->$singleField = 0;
552
553                 $values .= "{$singleField} = {$this->$singleField} ";
554                 }
555                 else
556                     $values .= "{$singleField} = '{$this->$singleField}' ";
557             }
558
559             $query = "UPDATE outbound_email set {$values} WHERE type='system-override' ";
560
561             $this->db->query($query);
562         }
563         /**
564          * Remove all of the user override accounts.
565          *
566          */
567         function removeUserOverrideAccounts()
568         {
569             $query = "DELETE FROM outbound_email WHERE type = 'system-override'";
570                 return $this->db->query($query);
571         }
572         /**
573          * Deletes an instance
574          */
575         function delete() {
576                 if(empty($this->id)) {
577                         return false;
578                 }
579
580                 $q = "DELETE FROM outbound_email WHERE id = '{$this->id}'";
581                 return $this->db->query($q);
582         }
583
584         private function _getOutboundServerDisplay(
585             $smtptype,
586             $smtpserver
587             )
588         {
589             global $app_strings;
590
591             switch ($smtptype) {
592         case "yahoomail":
593             return $app_strings['LBL_SMTPTYPE_YAHOO']; break;
594         case "gmail":
595             return $app_strings['LBL_SMTPTYPE_GMAIL']; break;
596         case "exchange":
597             return $smtpserver . ' - ' . $app_strings['LBL_SMTPTYPE_EXCHANGE']; break;
598         default:
599             return $smtpserver; break;
600         }
601         }
602
603         /**
604          * Get mailer for current user by name
605          * @param User $user
606          * @param string $name
607          * @return OutboundEmail|false
608          */
609         public function getMailerByName($user, $name)
610         {
611             if($name == "system" && !$this->isAllowUserAccessToSystemDefaultOutbound()) {
612                 $oe = $this->getUsersMailerForSystemOverride($user->id);
613                 if(!empty($oe) && !empty($oe->id)) {
614                     return $oe;
615                 }
616             else  {
617                 return $this->getSystemMailerSettings();
618             }
619             }
620             $res = $this->db->query("SELECT id FROM outbound_email WHERE user_id = '{$user->id}' AND name='".$this->db->quote($name)."'");
621                 $a = $this->db->fetchByAssoc($res);
622         if(!isset($a['id'])) {
623             return false;
624         }
625             return $this->retrieve($a['id']);
626         }
627 }