]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - modules/EmailTemplates/EmailTemplate.php
Release 6.5.10
[Github/sugarcrm.git] / modules / EmailTemplates / EmailTemplate.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-2013 SugarCRM Inc.
6  * 
7  * This program is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU Affero General Public License version 3 as published by the
9  * Free Software Foundation with the addition of the following permission added
10  * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
11  * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
12  * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
13  * 
14  * This program is distributed in the hope that it will be useful, but WITHOUT
15  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16  * FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
17  * details.
18  * 
19  * You should have received a copy of the GNU Affero General Public License along with
20  * this program; if not, see http://www.gnu.org/licenses or write to the Free
21  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22  * 02110-1301 USA.
23  * 
24  * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
25  * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
26  * 
27  * The interactive user interfaces in modified source and object code versions
28  * of this program must display Appropriate Legal Notices, as required under
29  * Section 5 of the GNU Affero General Public License version 3.
30  * 
31  * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
32  * these Appropriate Legal Notices must retain the display of the "Powered by
33  * SugarCRM" logo. If the display of the logo is not reasonably feasible for
34  * technical reasons, the Appropriate Legal Notices must display the words
35  * "Powered by SugarCRM".
36  ********************************************************************************/
37
38 /*********************************************************************************
39
40  * Description:  TODO: To be written.
41  * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
42  * All Rights Reserved.
43  * Contributor(s): ______________________________________..
44  ********************************************************************************/
45
46
47
48
49
50
51 // EmailTemplate is used to store email email_template information.
52 class EmailTemplate extends SugarBean {
53         var $field_name_map = array();
54         // Stored fields
55         var $id;
56         var $date_entered;
57         var $date_modified;
58         var $modified_user_id;
59         var $created_by;
60         var $created_by_name;
61         var $modified_by_name;
62     var $assigned_user_id;
63     var $assigned_user_name;
64         var $name;
65         var $published;
66         var $description;
67         var $body;
68         var $body_html;
69     var $subject;
70         var $attachments;
71         var $from_name;
72         var $from_address;
73         var $table_name = "email_templates";
74         var $object_name = "EmailTemplate";
75         var $module_dir = "EmailTemplates";
76         var $new_schema = true;
77         // This is used to retrieve related fields from form posts.
78         var $additional_column_fields = array(
79         );
80         // add fields here that would not make sense in an email template
81         var $badFields = array(
82                 'account_description',
83                 'contact_id',
84                 'lead_id',
85                 'opportunity_amount',
86                 'opportunity_id',
87                 'opportunity_name',
88                 'opportunity_role_id',
89                 'opportunity_role_fields',
90                 'opportunity_role',
91                 'campaign_id',
92                 // User objects
93                 'id',
94                 'date_entered',
95                 'date_modified',
96                 'user_preferences',
97                 'accept_status',
98                 'user_hash',
99                 'authenticate_id',
100                 'sugar_login',
101                 'reports_to_id',
102                 'reports_to_name',
103                 'is_admin',
104                 'receive_notifications',
105                 'modified_user_id',
106                 'modified_by_name',
107                 'created_by',
108                 'created_by_name',
109                 'accept_status_id',
110                 'accept_status_name',
111         );
112
113     /**
114      * @var array temp storage for template variables while cleanBean
115      */
116     protected $storedVariables = array();
117
118         function EmailTemplate() {
119                 parent::SugarBean();
120         }
121
122         /**
123          * Generates the extended field_defs for creating macros
124          * @param object $bean SugarBean
125          * @param string $prefix "contact_", "user_" etc.
126          * @return
127          */
128         function generateFieldDefsJS() {
129                 global $current_user;
130
131
132
133
134
135                 $contact = new Contact();
136                 $account = new Account();
137                 $lead = new Lead();
138                 $prospect = new Prospect();
139
140
141                 $loopControl = array(
142                         'Contacts' => array(
143                             'Contacts' => $contact,
144                             'Leads' => $lead,
145                                 'Prospects' => $prospect,
146                         ),
147                         'Accounts' => array(
148                                 'Accounts' => $account,
149                         ),
150                         'Users' => array(
151                                 'Users' => $current_user,
152                         ),
153                 );
154
155                 $prefixes = array(
156                         'Contacts' => 'contact_',
157                         'Accounts' => 'account_',
158                         'Users' => 'contact_user_',
159                 );
160
161                 $collection = array();
162                 foreach($loopControl as $collectionKey => $beans) {
163                         $collection[$collectionKey] = array();
164                         foreach($beans as $beankey => $bean) {
165
166                                 foreach($bean->field_defs as $key => $field_def) {
167                                     if( ($field_def['type'] == 'relate' && empty($field_def['custom_type'])) ||
168                                                 ($field_def['type'] == 'assigned_user_name' || $field_def['type'] =='link') ||
169                                                 ($field_def['type'] == 'bool') ||
170                                                 (in_array($field_def['name'], $this->badFields)) ) {
171                                         continue;
172                                     }
173                                     if(!isset($field_def['vname'])) {
174                                         //echo $key;
175                                     }
176                                     // valid def found, process
177                                     $optionKey = strtolower("{$prefixes[$collectionKey]}{$key}");
178                                     $optionLabel = preg_replace('/:$/', "", translate($field_def['vname'], $beankey));
179                                     $dup=1;
180                                     foreach ($collection[$collectionKey] as $value){
181                                         if($value['name']==$optionKey){
182                                                 $dup=0;
183                                                 break;
184                                         }
185                                     }
186                                     if($dup)
187                                         $collection[$collectionKey][] = array("name" => $optionKey, "value" => $optionLabel);
188                                 }
189                         }
190                 }
191
192                 $json = getJSONobj();
193                 $ret = "var field_defs = ";
194                 $ret .= $json->encode($collection, false);
195                 $ret .= ";";
196                 return $ret;
197         }
198
199         function get_summary_text() {
200                 return "$this->name";
201         }
202
203         function create_export_query(&$order_by, &$where) {
204                 return $this->create_new_list_query($order_by, $where);
205         }
206
207         function fill_in_additional_list_fields() {
208                 $this->fill_in_additional_parent_fields();
209         }
210
211         function fill_in_additional_detail_fields() {
212             if (empty($this->body) && !empty($this->body_html))
213         {
214             global $sugar_config;
215             $this->body = strip_tags(html_entity_decode($this->body_html, ENT_COMPAT, $sugar_config['default_charset']));
216         }
217                 $this->created_by_name = get_assigned_user_name($this->created_by);
218                 $this->modified_by_name = get_assigned_user_name($this->modified_user_id);
219         $this->assigned_user_name = get_assigned_user_name($this->assigned_user_id);
220                 $this->fill_in_additional_parent_fields();
221         }
222
223         function fill_in_additional_parent_fields() {
224         }
225
226         function get_list_view_data() {
227                 global $app_list_strings, $focus, $action, $currentModule;
228                 $fields = $this->get_list_view_array();
229                 $fields["DATE_MODIFIED"] = substr($fields["DATE_MODIFIED"], 0 , 10);
230                 return $fields;
231         }
232
233 //function all string that match the pattern {.} , also catches the list of found strings.
234     //the cache will get refreshed when the template bean instance changes.
235     //The found url key patterns are replaced with name value pairs provided as function parameter. $tracked_urls.
236     //$url_template is used to construct the url for the email message. the template should have place holder for 1 variable parameter, represented by %1
237     //$template_text_array is a list of text strings that need to be searched. usually the subject, html body and text body of the email message.
238     //$removeme_url_template, if the url has is_optout property checked then use this template.
239     function parse_tracker_urls($template_text_array,$url_template,$tracked_urls,$removeme_url_template) {
240         global $beanFiles,$beanList, $app_list_strings,$sugar_config;
241         if (!isset($this->parsed_urls))
242             $this->parsed_urls=array();
243
244         $return_array = $template_text_array;
245         if(count($tracked_urls) > 0)
246         {
247             //parse the template and find all the dynamic strings that need replacement.
248             foreach ($template_text_array as $key=>$template_text) {
249                 if (!empty($template_text)) {
250
251                     if(!isset($this->parsed_urls[$key]) || $this->parsed_urls[$key]['text'] != $template_text) {
252                         // Fix for bug52014.
253                         $template_text = urldecode($template_text);
254                         $matches = $this->_preg_match_tracker_url($template_text);
255                         $count = count($matches[0]);
256                         $this->parsed_urls[$key]=array('matches' => $matches, 'text' => $template_text);
257                     } else {
258                         $matches=$this->parsed_urls[$key]['matches'];
259                         if(!empty($matches[0])) {
260                             $count=count($matches[0]);
261                         } else {
262                             $count=0;
263                         }
264                     }
265
266                     //navigate thru all the matched keys and replace the keys with actual strings.
267
268                     if($count > 0)
269                     {
270                         for ($i=($count -1); $i>=0; $i--) {
271                             $url_key_name=$matches[0][$i][0];
272                             if (!empty($tracked_urls[$url_key_name])) {
273                                 if ($tracked_urls[$url_key_name]['is_optout']==1){
274                                     $tracker_url = $removeme_url_template;
275                                 } else {
276                                     $tracker_url = sprintf($url_template,$tracked_urls[$url_key_name]['id']);
277                                 }
278                             }
279                             if(!empty($tracker_url) && !empty($template_text) && !empty($matches[0][$i][0]) && !empty($tracked_urls[$matches[0][$i][0]])){
280                                 $template_text=substr_replace($template_text,$tracker_url,$matches[0][$i][1], strlen($matches[0][$i][0]));
281                                 $template_text=str_replace($sugar_config['site_url'].'/'.$sugar_config['site_url'],$sugar_config['site_url'],$template_text);
282                             }
283                         }
284                     }
285                 }
286                 $return_array[$key]=$template_text;
287             }
288         }
289         return $return_array;
290     }
291
292     /**
293      *
294      * Method for replace "preg_match_all" in method "parse_tracker_urls"
295      * @param $text string String in which we need to search all string that match the pattern {.}
296      * @return array result of search
297      */
298     private function _preg_match_tracker_url($text)
299     {
300         $result = array();
301         $ind = 0;
302         $switch = false;
303         for($i = 0; $i < strlen($text); $i++)
304         {
305             if($text[$i] == '{')
306             {
307                 $ind = $i;
308                 $switch = true;
309             }
310             elseif($text[$i] == '}' && $switch === true)
311             {
312                 $switch = false;
313                 array_push($result, array(substr($text, $ind, $i - $ind + 1), $ind));
314             }
315         }
316         return array($result);
317     }
318
319         function parse_email_template($template_text_array, $focus_name, $focus, &$macro_nv) {
320
321
322                 global $beanFiles, $beanList, $app_list_strings;
323
324                 // generate User instance that owns this "Contact" for contact_user_* macros
325                 $user = new User();
326         if(isset($focus->assigned_user_id)  && !empty($focus->assigned_user_id)){
327                   $user->retrieve($focus->assigned_user_id);
328         }
329
330                 if(!isset($this->parsed_entities))
331                         $this->parsed_entities=array();
332
333                 //parse the template and find all the dynamic strings that need replacement.
334         // Bug #48111 It's strange why prefix for User module is contact_user (see self::generateFieldDefsJS method)
335         if ($beanList[$focus_name] == 'User')
336         {
337             $pattern_prefix = '$contact_user_';
338         }
339         else
340         {
341             $pattern_prefix = '$'.strtolower($beanList[$focus_name]).'_';
342         }
343                 $pattern_prefix_length = strlen($pattern_prefix);
344                 $pattern = '/\\'.$pattern_prefix.'[A-Za-z_0-9]*/';
345
346                 foreach($template_text_array as $key=>$template_text) {
347                         if(!isset($this->parsed_entities[$key])) {
348                                 $matches = array();
349                                 $count = preg_match_all($pattern, $template_text, $matches, PREG_OFFSET_CAPTURE);
350
351                                 if($count != 0) {
352                                         for($i=($count -1); $i>=0; $i--) {
353                                                 if(!isset($matches[0][$i][2])) {
354                                                         //find the field name in the bean.
355                                                         $matches[0][$i][2]=substr($matches[0][$i][0],$pattern_prefix_length,strlen($matches[0][$i][0]) - $pattern_prefix_length);
356
357                                                         //store the localized strings if the field is of type enum..
358                                                         if(isset($focus->field_defs[$matches[0][$i][2]]) && $focus->field_defs[$matches[0][$i][2]]['type']=='enum' && isset($focus->field_defs[$matches[0][$i][2]]['options'])) {
359                                                                 $matches[0][$i][3]=$focus->field_defs[$matches[0][$i][2]]['options'];
360                                                         }
361                                                 }
362                                         }
363                                 }
364                                 $this->parsed_entities[$key]=$matches;
365                         } else {
366                                 $matches=$this->parsed_entities[$key];
367                                 if(!empty($matches[0])) {
368                                         $count=count($matches[0]);
369                                 } else {
370                                         $count=0;
371                                 }
372                         }
373
374                         for ($i=($count -1); $i>=0; $i--) {
375                                 $field_name=$matches[0][$i][2];
376
377                                 // cn: feel for User object attribute key and assign as found
378                                 if(strpos($field_name, "user_") === 0) {
379                                         $userFieldName = substr($field_name, 5);
380                                         $value = $user->$userFieldName;
381                                         //_pp($userFieldName."[{$value}]");
382                                 } else {
383                                         $value = $focus->{$field_name};
384                                 }
385
386                                 //check dom
387                                 if(isset($matches[0][$i][3])) {
388                                         if(isset($app_list_strings[$matches[0][$i][3]][$value])) {
389                                                 $value=$app_list_strings[$matches[0][$i][3]][$value];
390                                         }
391                                 }
392
393                 //generate name value pair array of macros and corresponding values for the targed.
394                 $macro_nv[$matches[0][$i][0]] =$value;
395
396                                 $template_text=substr_replace($template_text,$value,$matches[0][$i][1], strlen($matches[0][$i][0]));
397                         }
398
399                         //parse the template for tracker url strings. patter for these strings in {[a-zA-Z_0-9]+}
400
401                         $return_array[$key]=$template_text;
402                 }
403
404                 return $return_array;
405         }
406
407     /**
408      * Convenience method to convert raw value into appropriate type format
409      * @param string $type
410      * @param string $value
411      * @return string
412      */
413     function _convertToType($type,$value) {
414         switch($type) {
415             case 'currency' : return currency_format_number($value);
416             default: return $value;
417         }
418     }
419
420         /**
421          * Convenience method to parse for user's values in a template
422          * @param array $repl_arr
423          * @param object $user
424          * @return array
425          */
426         function _parseUserValues($repl_arr, &$user) {
427                 foreach($user->field_defs as $field_def) {
428                         if(($field_def['type'] == 'relate' && empty($field_def['custom_type'])) || $field_def['type'] == 'assigned_user_name') {
429                         continue;
430                         }
431
432                         if($field_def['type'] == 'enum') {
433                                 $translated = translate($field_def['options'], 'Users', $user->$field_def['name']);
434
435                                 if(isset($translated) && ! is_array($translated)) {
436                                         $repl_arr["contact_user_".$field_def['name']] = $translated;
437                                 } else { // unset enum field, make sure we have a match string to replace with ""
438                                         $repl_arr["contact_user_".$field_def['name']] = '';
439                                 }
440                         } else {
441                                 if(isset($user->$field_def['name'])) {
442                     // bug 47647 - allow for fields to translate before adding to template
443                                         $repl_arr["contact_user_".$field_def['name']] = self::_convertToType($field_def['type'],$user->$field_def['name']);
444                                 } else {
445                                         $repl_arr["contact_user_".$field_def['name']] = "";
446                                 }
447                         }
448                 }
449
450                 return $repl_arr;
451         }
452
453
454         function parse_template_bean($string, $bean_name, &$focus) {
455                 global $current_user;
456                 global $beanFiles, $beanList;
457                 $repl_arr = array();
458
459                 // cn: bug 9277 - create a replace array with empty strings to blank-out invalid vars
460                 $acct = new Account();
461                 $contact = new Contact();
462                 $lead = new Lead();
463                 $prospect = new Prospect();
464
465                 foreach($lead->field_defs as $field_def) {
466                         if(($field_def['type'] == 'relate' && empty($field_def['custom_type'])) || $field_def['type'] == 'assigned_user_name') {
467                         continue;
468                         }
469             $repl_arr = EmailTemplate::add_replacement($repl_arr, $field_def, array(
470                 'contact_'         . $field_def['name'] => '',
471                 'contact_account_' . $field_def['name'] => '',
472             ));
473                 }
474                 foreach($prospect->field_defs as $field_def) {
475                         if(($field_def['type'] == 'relate' && empty($field_def['custom_type'])) || $field_def['type'] == 'assigned_user_name') {
476                         continue;
477                         }
478             $repl_arr = EmailTemplate::add_replacement($repl_arr, $field_def, array(
479                 'contact_'         . $field_def['name'] => '',
480                 'contact_account_' . $field_def['name'] => '',
481             ));
482                 }
483                 foreach($contact->field_defs as $field_def) {
484                         if(($field_def['type'] == 'relate' && empty($field_def['custom_type'])) || $field_def['type'] == 'assigned_user_name') {
485                         continue;
486                         }
487             $repl_arr = EmailTemplate::add_replacement($repl_arr, $field_def, array(
488                 'contact_'         . $field_def['name'] => '',
489                 'contact_account_' . $field_def['name'] => '',
490             ));
491                 }
492                 foreach($acct->field_defs as $field_def) {
493                         if(($field_def['type'] == 'relate' && empty($field_def['custom_type'])) || $field_def['type'] == 'assigned_user_name') {
494                         continue;
495                         }
496             $repl_arr = EmailTemplate::add_replacement($repl_arr, $field_def, array(
497                 'account_'         . $field_def['name'] => '',
498                 'account_contact_' . $field_def['name'] => '',
499             ));
500                 }
501                 // cn: end bug 9277 fix
502
503
504                 // feel for Parent account, only for Contacts traditionally, but written for future expansion
505                 if(isset($focus->account_id) && !empty($focus->account_id)) {
506                         $acct->retrieve($focus->account_id);
507                 }
508
509                 if($bean_name == 'Contacts') {
510                         // cn: bug 9277 - email templates not loading account/opp info for templates
511                         if(!empty($acct->id)) {
512                                 foreach($acct->field_defs as $field_def) {
513                                         if(($field_def['type'] == 'relate' && empty($field_def['custom_type'])) || $field_def['type'] == 'assigned_user_name') {
514                                 continue;
515                                         }
516
517                                         if($field_def['type'] == 'enum') {
518                                                 $translated = translate($field_def['options'], 'Accounts' ,$acct->$field_def['name']);
519
520                                                 if(isset($translated) && ! is_array($translated)) {
521                             $repl_arr = EmailTemplate::add_replacement($repl_arr, $field_def, array(
522                                 'account_'         . $field_def['name'] => $translated,
523                                 'contact_account_' . $field_def['name'] => $translated,
524                             ));
525                                                 } else { // unset enum field, make sure we have a match string to replace with ""
526                             $repl_arr = EmailTemplate::add_replacement($repl_arr, $field_def, array(
527                                 'account_'         . $field_def['name'] => '',
528                                 'contact_account_' . $field_def['name'] => '',
529                             ));
530                                                 }
531                                         } else {
532                         // bug 47647 - allow for fields to translate before adding to template
533                         $translated = self::_convertToType($field_def['type'],$acct->$field_def['name']);
534                         $repl_arr = EmailTemplate::add_replacement($repl_arr, $field_def, array(
535                             'account_'         . $field_def['name'] => $translated,
536                             'contact_account_' . $field_def['name'] => $translated,
537                         ));
538                                         }
539                                 }
540                         }
541
542                         if(!empty($focus->assigned_user_id)) {
543                                 $user = new User();
544                                 $user->retrieve($focus->assigned_user_id);
545                                 $repl_arr = EmailTemplate::_parseUserValues($repl_arr, $user);
546                         }
547                 } elseif($bean_name == 'Users') {
548                         /**
549                          * This section of code will on do work when a blank Contact, Lead,
550                          * etc. is passed in to parse the contact_* vars.  At this point,
551                          * $current_user will be used to fill in the blanks.
552                          */
553                         $repl_arr = EmailTemplate::_parseUserValues($repl_arr, $current_user);
554                 } else {
555                         // assumed we have an Account in focus
556                         foreach($contact->field_defs as $field_def) {
557                                 if(($field_def['type'] == 'relate' && empty($field_def['custom_type'])) || $field_def['type'] == 'assigned_user_name' || $field_def['type'] == 'link') {
558                         continue;
559                                 }
560
561                                 if($field_def['type'] == 'enum') {
562                                         $translated = translate($field_def['options'], 'Accounts' ,$contact->$field_def['name']);
563
564                                         if(isset($translated) && ! is_array($translated)) {
565                         $repl_arr = EmailTemplate::add_replacement($repl_arr, $field_def, array(
566                             'contact_'         . $field_def['name'] => $translated,
567                             'contact_account_' . $field_def['name'] => $translated,
568                         ));
569                                         } else { // unset enum field, make sure we have a match string to replace with ""
570                         $repl_arr = EmailTemplate::add_replacement($repl_arr, $field_def, array(
571                             'contact_'         . $field_def['name'] => '',
572                             'contact_account_' . $field_def['name'] => '',
573                         ));
574                                         }
575                                 } else {
576                                         if (isset($contact->$field_def['name'])) {
577                         // bug 47647 - allow for fields to translate before adding to template
578                         $translated = self::_convertToType($field_def['type'],$contact->$field_def['name']);
579                         $repl_arr = EmailTemplate::add_replacement($repl_arr, $field_def, array(
580                             'contact_'         . $field_def['name'] => $translated,
581                             'contact_account_' . $field_def['name'] => $translated,
582                         ));
583                                         } // if
584                                 }
585                         }
586                 }
587
588                 ///////////////////////////////////////////////////////////////////////
589                 ////    LOAD FOCUS DATA INTO REPL_ARR
590                 foreach($focus->field_defs as $field_def) {
591                         if(isset($focus->$field_def['name'])) {
592                                 if(($field_def['type'] == 'relate' && empty($field_def['custom_type'])) || $field_def['type'] == 'assigned_user_name') {
593                         continue;
594                                 }
595
596                                 if($field_def['type'] == 'enum' && isset($field_def['options'])) {
597                                         $translated = translate($field_def['options'],$bean_name,$focus->$field_def['name']);
598
599                                         if(isset($translated) && ! is_array($translated)) {
600                         $repl_arr = EmailTemplate::add_replacement($repl_arr, $field_def, array(
601                             strtolower($beanList[$bean_name])."_".$field_def['name'] => $translated,
602                         ));
603                                         } else { // unset enum field, make sure we have a match string to replace with ""
604                         $repl_arr = EmailTemplate::add_replacement($repl_arr, $field_def, array(
605                             strtolower($beanList[$bean_name])."_".$field_def['name'] => '',
606                         ));
607                                         }
608                                 } else {
609                     // bug 47647 - translate currencies to appropriate values
610                     $repl_arr = EmailTemplate::add_replacement($repl_arr, $field_def, array(
611                         strtolower($beanList[$bean_name])."_".$field_def['name'] => self::_convertToType($field_def['type'],$focus->$field_def['name']),
612                     ));
613                                 }
614                         } else {
615                                 if($field_def['name'] == 'full_name') {
616                     $repl_arr = EmailTemplate::add_replacement($repl_arr, $field_def, array(
617                         strtolower($beanList[$bean_name]).'_full_name' => $focus->get_summary_text(),
618                     ));
619                                 } else {
620                     $repl_arr = EmailTemplate::add_replacement($repl_arr, $field_def, array(
621                         strtolower($beanList[$bean_name])."_".$field_def['name'] => '',
622                     ));
623                                 }
624                         }
625                 } // end foreach()
626
627                 krsort($repl_arr);
628                 reset($repl_arr);
629                 //20595 add nl2br() to respect the multi-lines formatting
630                 if(isset($repl_arr['contact_primary_address_street'])){
631                     $repl_arr['contact_primary_address_street'] = nl2br($repl_arr['contact_primary_address_street']);
632                 }
633                 if(isset($repl_arr['contact_alt_address_street'])){
634                     $repl_arr['contact_alt_address_street'] = nl2br($repl_arr['contact_alt_address_street']);
635                 }
636
637                 foreach ($repl_arr as $name=>$value) {
638                         if($value != '' && is_string($value)) {
639                                 $string = str_replace("\$$name", $value, $string);
640                         } else {
641                                 $string = str_replace("\$$name", ' ', $string);
642                         }
643                 }
644
645                 return $string;
646         }
647
648     /**
649      * Add replacement(s) to the collection based on field definition
650      *
651      * @param array $data
652      * @param array $field_def
653      * @param array $replacement
654      * @return array
655      */
656     protected static function add_replacement($data, $field_def, $replacement)
657     {
658         foreach ($replacement as $key => $value)
659         {
660             // @see defect #48641
661             if ('multienum' == $field_def['type']) {
662                 $value = implode(', ', unencodeMultienum($value));
663             }
664             $data[$key] = $value;
665         }
666         return $data;
667     }
668
669         function parse_template($string, &$bean_arr) {
670                 global $beanFiles, $beanList;
671
672                 foreach($bean_arr as $bean_name => $bean_id) {
673                         require_once($beanFiles[$beanList[$bean_name]]);
674
675                         $focus = new $beanList[$bean_name];
676                         $result = $focus->retrieve($bean_id);
677
678                         if($bean_name == 'Leads' || $bean_name == 'Prospects') {
679                                 $bean_name = 'Contacts';
680                         }
681
682                         if(isset($this) && isset($this->module_dir) && $this->module_dir == 'EmailTemplates') {
683                                 $string = $this->parse_template_bean($string, $bean_name, $focus);
684                         } else {
685                                 $string = EmailTemplate::parse_template_bean($string, $bean_name, $focus);
686                         }
687                 }
688                 return $string;
689         }
690
691         function bean_implements($interface) {
692                 switch($interface) {
693                         case 'ACL':return true;
694                 }
695                 return false;
696         }
697
698     static function getTypeOptionsForSearch(){
699         $template = new EmailTemplate();
700         $optionKey = $template->field_defs['type']['options'];
701         $options = $GLOBALS['app_list_strings'][$optionKey];
702         if( ! is_admin($GLOBALS['current_user']) && isset($options['workflow']))
703             unset($options['workflow']);
704
705         return $options;
706     }
707
708         function is_used_by_email_marketing() {
709                 $query = "select id from email_marketing where template_id='$this->id' and deleted=0";
710                 $result = $this->db->query($query);
711                 if($this->db->fetchByAssoc($result)) {
712                         return true;
713                 }
714                 return false;
715         }
716
717     /**
718      * Allows us to save variables of template as they are
719      */
720     public function cleanBean()
721     {
722         $this->storedVariables = array();
723         $this->body_html = preg_replace_callback('/\{::[^}]+::\}/', array($this, 'storeVariables'), $this->body_html);
724         parent::cleanBean();
725         $this->body_html = str_replace(array_values($this->storedVariables), array_keys($this->storedVariables), $this->body_html);
726     }
727
728     /**
729      * Replacing variables of templates by their md5 hash
730      *
731      * @param array $text result of preg_replace_callback
732      * @return string md5 hash of result
733      */
734     protected function storeVariables($text)
735     {
736         if (isset($this->storedVariables[$text[0]]) == false) {
737             $this->storedVariables[$text[0]] = md5($text[0]);
738         }
739         return $this->storedVariables[$text[0]];
740     }
741 }
742 ?>