From 8881f8990c6842269c2e5385694578f6e024d8f7 Mon Sep 17 00:00:00 2001 From: John Mertic Date: Sat, 25 Aug 2012 00:37:30 -0400 Subject: [PATCH] Release 6.5.3 --- ModuleInstall/ModuleScanner.php | 1 + ModuleInstall/extensions.php | 1 + cache/include/javascript/sugar_grp1.js | 9 +- cache/include/javascript/sugar_grp_jsolait.js | 3 +- .../include/javascript/sugar_grp_quickcomp.js | 3 +- data/BeanFactory.php | 18 +- data/Link2.php | 3 +- data/Relationships/One2MBeanRelationship.php | 27 +- data/Relationships/One2MRelationship.php | 14 +- data/SugarBean.php | 50 +- download.php | 15 +- files.md5 | 307 +- include/DetailView/DetailView.tpl | 58 +- include/DetailView/header.tpl | 3 +- include/EditView/EditView.tpl | 61 +- include/EditView/EditView2.php | 3 +- include/EditView/Panels.js | 39 + include/EditView/SubpanelQuickEdit.php | 5 + include/EditView/SugarVCR.php | 145 +- include/EditView/SugarVCR.tpl | 73 + include/EditView/header.tpl | 3 +- include/ListView/ListView.php | 2 - include/ListView/ListViewGeneric.tpl | 3 +- include/ListView/ListViewSmarty.php | 1 + include/MySugar/tpls/MySugar.tpl | 1 + include/SearchForm/SearchForm2.php | 14 +- include/SubPanel/SubPanelTiles.php | 10 +- include/SugarCharts/Jit/JitReports.php | 48 +- include/SugarCharts/JsChart.php | 118 +- include/SugarCharts/SugarChart.php | 19 +- .../Fields/Base/SugarFieldBase.php | 14 +- .../Fields/Multienum/WirelessDetailView.tpl | 45 + .../Fields/Multienum/WirelessEditView.tpl | 42 + .../templates/company/vardefs.php | 1 + .../SugarObjects/templates/person/vardefs.php | 2 +- include/SugarPHPMailer.php | 12 + include/TemplateHandler/TemplateHandler.php | 57 +- include/database/MssqlManager.php | 5 +- include/externalAPI/ExternalAPIFactory.php | 4 +- .../SugarWidgets/SugarWidgetFielddatetime.php | 24 +- .../SugarWidgets/SugarWidgetReportField.php | 2 +- include/globalControlLinks.php | 1 + include/images/tour/FirstFrame.png | Bin 0 -> 9053 bytes include/images/tour/arrow.png | Bin 0 -> 4113 bytes include/images/tour/arrow_ie.png | Bin 0 -> 19079 bytes include/images/tour/profile_link.png | Bin 0 -> 12299 bytes include/javascript/jquery/bootstrap.min.js | 6 + .../jquery/jquery.effects.custombounce.js | 123 + .../javascript/jquery/jquery.popoverext.js | 186 + include/javascript/jsclass_async.js | 3 +- include/javascript/sugar_3.js | 2 +- include/javascript/tour.js | 43 + include/language/en_us.lang.php | 13 + include/phpmailer/{license.txt => LICENSE} | 0 include/phpmailer/README | 44 +- include/phpmailer/class.phpmailer.php | 1860 +++-- include/phpmailer/class.smtp.php | 578 +- include/phpmailer/extras/htmlfilter.php | 861 +++ .../phpmailer/language/phpmailer.lang-ar.php | 67 +- .../phpmailer/language/phpmailer.lang-br.php | 74 +- .../phpmailer/language/phpmailer.lang-ca.php | 73 +- .../phpmailer/language/phpmailer.lang-ch.php | 26 + .../phpmailer/language/phpmailer.lang-cz.php | 76 +- .../phpmailer/language/phpmailer.lang-de.php | 76 +- .../phpmailer/language/phpmailer.lang-dk.php | 74 +- .../phpmailer/language/phpmailer.lang-es.php | 76 +- .../phpmailer/language/phpmailer.lang-et.php | 69 +- .../phpmailer/language/phpmailer.lang-fi.php | 75 +- .../phpmailer/language/phpmailer.lang-fo.php | 77 +- .../phpmailer/language/phpmailer.lang-fr.php | 75 +- .../phpmailer/language/phpmailer.lang-hu.php | 73 +- .../phpmailer/language/phpmailer.lang-it.php | 79 +- .../phpmailer/language/phpmailer.lang-ja.php | Bin 2670 -> 1705 bytes .../phpmailer/language/phpmailer.lang-nl.php | 75 +- .../phpmailer/language/phpmailer.lang-no.php | 75 +- .../phpmailer/language/phpmailer.lang-pl.php | 73 +- .../phpmailer/language/phpmailer.lang-ro.php | 74 +- .../phpmailer/language/phpmailer.lang-ru.php | 72 +- .../phpmailer/language/phpmailer.lang-se.php | 76 +- .../phpmailer/language/phpmailer.lang-tr.php | 80 +- .../phpmailer/language/phpmailer.lang-zh.php | 26 + .../language/phpmailer.lang-zh_cn.php | 26 + include/utils.php | 21 + include/utils/layout_utils.php | 3 +- install/language/en_us.lang.php | 2 +- json_server.php | 16 +- jssource/JSGroupings.php | 5 +- jssource/src_files/include/EditView/Panels.js | 66 + .../include/javascript/jsclass_async.js | 8 +- .../src_files/include/javascript/sugar_3.js | 1 + jssource/src_files/include/javascript/tour.js | 241 + jssource/src_files/modules/Home/tour.js | 125 + .../Administration/language/en_us.lang.php | 1 + .../metadata/adminpaneldefs.php | 4 + modules/Calls/Call.php | 18 +- modules/Calls/CallHelper.php | 3 +- modules/Calls/metadata/detailviewdefs.php | 2 +- modules/Campaigns/WebToLeadFormSave.php | 3 +- modules/Configurator/Configurator.php | 7 + modules/Configurator/UploadFileCheck.php | 2 +- modules/Contacts/ContactFormBase.php | 21 +- .../templates/Fields/Forms/coreBottom.tpl | 20 +- modules/EmailMarketing/EditView.html | 8 +- modules/Emails/EmailUI.php | 4 + modules/Employees/Employee.php | 1 - modules/Home/action_view_map.php | 1 + modules/Home/index.php | 1 - modules/Home/language/en_us.lang.php | 28 + modules/Home/tour.css | 276 + modules/Home/tour.js | 35 + modules/Home/tour.tpl | 98 + modules/Home/views/view.tour.php | 49 + modules/InboundEmail/InboundEmail.php | 24 +- modules/ModuleBuilder/Module/StudioModule.php | 22 +- modules/ModuleBuilder/javascript/studio2.js | 17 +- modules/ModuleBuilder/language/en_us.lang.php | 11 +- .../ModuleBuilder/parsers/ParserFactory.php | 2 +- .../views/GridLayoutMetaDataParser.php | 89 +- modules/ModuleBuilder/tpls/layoutView.tpl | 63 +- .../ModuleBuilder/views/view.layoutview.php | 1 + modules/Project/tpls/QuickEditFooter.tpl | 61 + modules/Project/tpls/QuickEditHeader.tpl | 104 + modules/Project/views/view.quickedit.php | 84 + modules/Schedulers/_AddJobsHere.php | 4 +- modules/UpgradeWizard/end.php | 11 +- modules/UpgradeWizard/silentUpgrade_step2.php | 10 + modules/Users/Changenewpassword.php | 3 +- modules/Users/Save.php | 2 +- modules/Users/UpdateTourStatus.php | 42 + modules/Users/login.tpl | 18 +- modules/Users/tpls/EditViewFooter.tpl | 5 + modules/Users/tpls/EditViewHeader.tpl | 14 +- modules/Users/vardefs.php | 3 +- modules/vCals/vCal.php | 8 +- service/core/SoapHelperWebService.php | 8 +- service/core/SugarWebServiceImpl.php | 3 + service/core/webservice.php | 2 + service/v3/SugarWebServiceUtilv3.php | 1 + service/v3_1/SugarWebServiceImplv3_1.php | 4 + service/v4/SugarWebServiceUtilv4.php | 4 +- service/v4_1/SugarWebServiceUtilv4_1.php | 1 + soap/SoapHelperFunctions.php | 3 + sugar_version.php | 8 +- tests/data/Bug49505Test.php | 106 + tests/data/Bug53223Test.php | 1 + tests/include/SugarCharts/Bug42326Test.php | 4 +- tests/include/database/DBManagerTest.php | 85 + tests/include/vCard/vCardTest.php | 17 +- tests/jssource/bug54472.php | 148 + tests/modules/Calls/CallHelperTest.php | 7 +- tests/modules/Calls/CallTest.php | 1 + .../ModuleBuilder/Module/Bug46196Test.php | 138 - themes/Sugar5/css/style.css | 8 +- themes/default/css/bootstrap.css | 6410 +++++++++++++++++ themes/default/font/fontawesome-webfont.eot | Bin 0 -> 42272 bytes themes/default/font/fontawesome-webfont.svg | 175 + themes/default/font/fontawesome-webfont.svgz | Bin 0 -> 21845 bytes themes/default/font/fontawesome-webfont.ttf | Bin 0 -> 41907 bytes themes/default/font/fontawesome-webfont.woff | Bin 0 -> 23416 bytes themes/default/less/accordion.less | 32 + themes/default/less/alerts.less | 73 + themes/default/less/bootstrap-mobile.less | 58 + themes/default/less/bootstrap.less | 69 + themes/default/less/breadcrumbs.less | 22 + themes/default/less/button-groups.less | 150 + themes/default/less/buttons.less | 208 + themes/default/less/carousel.less | 121 + themes/default/less/chosen.less | 395 + themes/default/less/close.less | 18 + themes/default/less/code.less | 57 + themes/default/less/component-animations.less | 18 + themes/default/less/dropdowns.less | 130 + themes/default/less/font-awesome.less | 300 + themes/default/less/forms.less | 532 ++ themes/default/less/grid.less | 8 + themes/default/less/hero-unit.less | 20 + themes/default/less/labels.less | 50 + themes/default/less/layouts.less | 17 + themes/default/less/mixins.less | 629 ++ themes/default/less/modals.less | 83 + themes/default/less/navbar.less | 301 + themes/default/less/navs.less | 353 + themes/default/less/pager.less | 30 + themes/default/less/pagination.less | 55 + themes/default/less/popovers.less | 75 + themes/default/less/progress-bars.less | 128 + themes/default/less/reset.less | 126 + themes/default/less/responsive.less | 126 + themes/default/less/scaffolding.less | 29 + themes/default/less/sprites.less | 165 + themes/default/less/sugar.less | 1427 ++++ themes/default/less/sugarmobile.less | 868 +++ themes/default/less/tables.less | 180 + themes/default/less/thumbnails.less | 33 + themes/default/less/tooltip.less | 35 + themes/default/less/type.less | 218 + themes/default/less/utilities.less | 34 + themes/default/less/variables.less | 207 + themes/default/less/wells.less | 17 + 199 files changed, 19923 insertions(+), 2828 deletions(-) create mode 100644 include/EditView/Panels.js create mode 100644 include/EditView/SugarVCR.tpl create mode 100644 include/SugarFields/Fields/Multienum/WirelessDetailView.tpl create mode 100644 include/SugarFields/Fields/Multienum/WirelessEditView.tpl create mode 100644 include/images/tour/FirstFrame.png create mode 100644 include/images/tour/arrow.png create mode 100644 include/images/tour/arrow_ie.png create mode 100644 include/images/tour/profile_link.png create mode 100644 include/javascript/jquery/bootstrap.min.js create mode 100644 include/javascript/jquery/jquery.effects.custombounce.js create mode 100644 include/javascript/jquery/jquery.popoverext.js create mode 100644 include/javascript/tour.js rename include/phpmailer/{license.txt => LICENSE} (100%) create mode 100644 include/phpmailer/extras/htmlfilter.php create mode 100644 include/phpmailer/language/phpmailer.lang-ch.php create mode 100644 include/phpmailer/language/phpmailer.lang-zh.php create mode 100644 include/phpmailer/language/phpmailer.lang-zh_cn.php create mode 100644 jssource/src_files/include/EditView/Panels.js create mode 100644 jssource/src_files/include/javascript/tour.js create mode 100644 jssource/src_files/modules/Home/tour.js create mode 100644 modules/Home/tour.css create mode 100644 modules/Home/tour.js create mode 100644 modules/Home/tour.tpl create mode 100644 modules/Home/views/view.tour.php create mode 100644 modules/Project/tpls/QuickEditFooter.tpl create mode 100644 modules/Project/tpls/QuickEditHeader.tpl create mode 100644 modules/Project/views/view.quickedit.php create mode 100644 modules/Users/UpdateTourStatus.php create mode 100755 tests/data/Bug49505Test.php create mode 100755 tests/jssource/bug54472.php delete mode 100755 tests/modules/ModuleBuilder/Module/Bug46196Test.php create mode 100644 themes/default/css/bootstrap.css create mode 100644 themes/default/font/fontawesome-webfont.eot create mode 100644 themes/default/font/fontawesome-webfont.svg create mode 100644 themes/default/font/fontawesome-webfont.svgz create mode 100644 themes/default/font/fontawesome-webfont.ttf create mode 100644 themes/default/font/fontawesome-webfont.woff create mode 100644 themes/default/less/accordion.less create mode 100644 themes/default/less/alerts.less create mode 100644 themes/default/less/bootstrap-mobile.less create mode 100644 themes/default/less/bootstrap.less create mode 100644 themes/default/less/breadcrumbs.less create mode 100644 themes/default/less/button-groups.less create mode 100644 themes/default/less/buttons.less create mode 100644 themes/default/less/carousel.less create mode 100644 themes/default/less/chosen.less create mode 100644 themes/default/less/close.less create mode 100644 themes/default/less/code.less create mode 100644 themes/default/less/component-animations.less create mode 100644 themes/default/less/dropdowns.less create mode 100644 themes/default/less/font-awesome.less create mode 100644 themes/default/less/forms.less create mode 100644 themes/default/less/grid.less create mode 100644 themes/default/less/hero-unit.less create mode 100644 themes/default/less/labels.less create mode 100644 themes/default/less/layouts.less create mode 100644 themes/default/less/mixins.less create mode 100644 themes/default/less/modals.less create mode 100644 themes/default/less/navbar.less create mode 100644 themes/default/less/navs.less create mode 100644 themes/default/less/pager.less create mode 100644 themes/default/less/pagination.less create mode 100644 themes/default/less/popovers.less create mode 100644 themes/default/less/progress-bars.less create mode 100644 themes/default/less/reset.less create mode 100644 themes/default/less/responsive.less create mode 100644 themes/default/less/scaffolding.less create mode 100644 themes/default/less/sprites.less create mode 100644 themes/default/less/sugar.less create mode 100644 themes/default/less/sugarmobile.less create mode 100644 themes/default/less/tables.less create mode 100644 themes/default/less/thumbnails.less create mode 100644 themes/default/less/tooltip.less create mode 100644 themes/default/less/type.less create mode 100644 themes/default/less/utilities.less create mode 100644 themes/default/less/variables.less create mode 100644 themes/default/less/wells.less diff --git a/ModuleInstall/ModuleScanner.php b/ModuleInstall/ModuleScanner.php index 6b018ee3..b8a468ca 100644 --- a/ModuleInstall/ModuleScanner.php +++ b/ModuleInstall/ModuleScanner.php @@ -134,6 +134,7 @@ class ModuleScanner{ 'set_file_buffer', 'tmpfile', 'umask', + 'ini_set', 'eval', 'exec', 'system', diff --git a/ModuleInstall/extensions.php b/ModuleInstall/extensions.php index 519eca17..efb855e2 100644 --- a/ModuleInstall/extensions.php +++ b/ModuleInstall/extensions.php @@ -55,6 +55,7 @@ if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point'); "userpage" => array("section" => "user_page", "extdir" => "UserPage", "file" => 'userpage.ext.php', "module" => "Users"), "utils" => array("section" => "utils", "extdir" => "Utils", "file" => 'custom_utils.ext.php', "module" => "application"), "vardefs" => array("section" => "vardefs", "extdir" => "Vardefs", "file" => 'vardefs.ext.php'), + "jsgroupings" => array("section" => "jsgroups", "extdir" => "JSGroupings", "file" => 'jsgroups.ext.php'), ); if(file_exists("custom/application/Ext/Extensions/extensions.ext.php")) { include("custom/application/Ext/Extensions/extensions.ext.php"); diff --git a/cache/include/javascript/sugar_grp1.js b/cache/include/javascript/sugar_grp1.js index acc40550..40bb69b4 100644 --- a/cache/include/javascript/sugar_grp1.js +++ b/cache/include/javascript/sugar_grp1.js @@ -1,7 +1,7 @@ if(typeof(SUGAR)=="undefined"){SUGAR={namespace:function(ns){SUGAR[ns]=SUGAR[ns]||{};return((typeof SUGAR[ns]==="object")&&(SUGAR[ns]!==null))?SUGAR[ns]:false;},append:function(target,obj){for(var prop in obj){if(obj[prop]!==void 0)target[prop]=obj[prop];} return target;}};} -SUGAR.namespace("themes");SUGAR.namespace("sugarHome");SUGAR.namespace("subpanelUtils");SUGAR.namespace("ajaxStatusClass");SUGAR.namespace("tabChooser");SUGAR.namespace("utils");SUGAR.namespace("savedViews");SUGAR.namespace("dashlets");SUGAR.namespace("unifiedSearchAdvanced");SUGAR.namespace("searchForm");SUGAR.namespace("language");SUGAR.namespace("Studio");SUGAR.namespace("contextMenu");SUGAR.namespace("config");var nameIndex=0;var typeIndex=1;var requiredIndex=2;var msgIndex=3;var jstypeIndex=5;var minIndex=10;var maxIndex=11;var altMsgIndex=15;var compareToIndex=7;var arrIndex=12;var operatorIndex=13;var callbackIndex=16;var allowblank=8;var validate=new Array();var maxHours=24;var requiredTxt='Missing Required Field:';var invalidTxt='Invalid Value:';var secondsSinceLoad=0;var inputsWithErrors=new Array();var tabsWithErrors=new Array();var lastSubmitTime=0;var alertList=new Array();var oldStartsWith='';function isSupportedIE(){var userAgent=navigator.userAgent.toLowerCase();if(userAgent.indexOf("msie")!=-1&&userAgent.indexOf("mac")==-1&&userAgent.indexOf("opera")==-1){var version=navigator.appVersion.match(/MSIE (.\..)/)[1];if(version>=5.5&&version<10){return true;}else{return false;}}} +SUGAR.namespace("themes");SUGAR.namespace("tour");SUGAR.namespace("sugarHome");SUGAR.namespace("subpanelUtils");SUGAR.namespace("ajaxStatusClass");SUGAR.namespace("tabChooser");SUGAR.namespace("utils");SUGAR.namespace("savedViews");SUGAR.namespace("dashlets");SUGAR.namespace("unifiedSearchAdvanced");SUGAR.namespace("searchForm");SUGAR.namespace("language");SUGAR.namespace("Studio");SUGAR.namespace("contextMenu");SUGAR.namespace("config");var nameIndex=0;var typeIndex=1;var requiredIndex=2;var msgIndex=3;var jstypeIndex=5;var minIndex=10;var maxIndex=11;var altMsgIndex=15;var compareToIndex=7;var arrIndex=12;var operatorIndex=13;var callbackIndex=16;var allowblank=8;var validate=new Array();var maxHours=24;var requiredTxt='Missing Required Field:';var invalidTxt='Invalid Value:';var secondsSinceLoad=0;var inputsWithErrors=new Array();var tabsWithErrors=new Array();var lastSubmitTime=0;var alertList=new Array();var oldStartsWith='';function isSupportedIE(){var userAgent=navigator.userAgent.toLowerCase();if(userAgent.indexOf("msie")!=-1&&userAgent.indexOf("mac")==-1&&userAgent.indexOf("opera")==-1){var version=navigator.appVersion.match(/MSIE (.\..)/)[1];if(version>=5.5&&version<10){return true;}else{return false;}}} SUGAR.isIE=isSupportedIE();var isSafari=(navigator.userAgent.toLowerCase().indexOf('safari')!=-1);RegExp.escape=function(text){if(!arguments.callee.sRE){var specials=['/','.','*','+','?','|','(',')','[',']','{','}','\\'];arguments.callee.sRE=new RegExp('(\\'+specials.join('|\\')+')','g');} return text.replace(arguments.callee.sRE,'\\$1');} function addAlert(type,name,subtitle,description,time,redirect){var addIndex=alertList.length;alertList[addIndex]=new Array();alertList[addIndex]['name']=name;alertList[addIndex]['type']=type;alertList[addIndex]['subtitle']=subtitle;alertList[addIndex]['description']=replaceHTMLChars(description.replace(/
/gi,"\n"));alertList[addIndex]['time']=time;alertList[addIndex]['done']=0;alertList[addIndex]['redirect']=redirect;} @@ -885,3 +885,10 @@ if(!!double_encode||double_encode==null){for(symbol in hash_map){if(hash_map.has return text+entity;});} return string;}/* End of File include/javascript/phpjs/htmlentities.js */ + +function initPanel(id,state){panelId='detailpanel_'+id;expandPanel(id);if(state=='collapsed'){collapsePanel(id);}} +function expandPanel(id){var panelId='detailpanel_'+id;document.getElementById(panelId).className=document.getElementById(panelId).className.replace(/(expanded|collapsed)/ig,'')+' expanded';} +function collapsePanel(id){var panelId='detailpanel_'+id;document.getElementById(panelId).className=document.getElementById(panelId).className.replace(/(expanded|collapsed)/ig,'')+' collapsed';} +function setCollapseState(mod,panel,isCollapsed){var sugar_panel_collase=Get_Cookie("sugar_panel_collase");if(sugar_panel_collase==null){sugar_panel_collase={};}else{sugar_panel_collase=YAHOO.lang.JSON.parse(sugar_panel_collase);} +sugar_panel_collase[mod]=sugar_panel_collase[mod]||{};sugar_panel_collase[mod][panel]=isCollapsed;Set_Cookie('sugar_panel_collase',YAHOO.lang.JSON.stringify(sugar_panel_collase),30,'/','','');}/* End of File include/EditView/Panels.js */ + diff --git a/cache/include/javascript/sugar_grp_jsolait.js b/cache/include/javascript/sugar_grp_jsolait.js index 97d0a11a..2fe8f0b1 100644 --- a/cache/include/javascript/sugar_grp_jsolait.js +++ b/cache/include/javascript/sugar_grp_jsolait.js @@ -33,8 +33,7 @@ function method_callback(o){var resp=YAHOO.lang.JSON.parse(o.responseText),reque reqid=global_request_registry[request_id];if(typeof(reqid)!='undefined'){widget=global_request_registry[request_id][0];method_name=global_request_registry[request_id][1];widget[method_name](result);}} SugarClass.inherit("SugarVCalClient","SugarClass");function SugarVCalClient(){this.init();} SugarVCalClient.prototype.init=function(){} -SugarVCalClient.prototype.load=function(user_id,request_id){this.user_id=user_id;var vcal_server='./vcal_server.php?type=vfb&source=outlook&user_id='+user_id;if(typeof(window.combo_date_start)!='undefined'){var date_start=window.combo_date_start.datetime;vcal_server+='&datestart='+date_start;} -YAHOO.util.Connect.asyncRequest('GET',vcal_server,{success:function(result){if(typeof GLOBAL_REGISTRY.freebusy=='undefined'){GLOBAL_REGISTRY.freebusy=new Object();} +SugarVCalClient.prototype.load=function(user_id,request_id){this.user_id=user_id;YAHOO.util.Connect.asyncRequest('GET','./vcal_server.php?type=vfb&source=outlook&user_id='+user_id,{success:function(result){if(typeof GLOBAL_REGISTRY.freebusy=='undefined'){GLOBAL_REGISTRY.freebusy=new Object();} if(typeof GLOBAL_REGISTRY.freebusy_adjusted=='undefined'){GLOBAL_REGISTRY.freebusy_adjusted=new Object();} GLOBAL_REGISTRY.freebusy[user_id]=SugarVCalClient.prototype.parseResults(result.responseText,false);GLOBAL_REGISTRY.freebusy_adjusted[user_id]=SugarVCalClient.prototype.parseResults(result.responseText,true);global_request_registry[request_id][0].display();},failure:function(result){this.success(result);},argument:{result:result}});} SugarVCalClient.prototype.parseResults=function(textResult,adjusted){var match=/FREEBUSY.*?\:([\w]+)\/([\w]+)/g;var result;var timehash=new Object();var dst_start;var dst_end;if(GLOBAL_REGISTRY.current_user.fields.dst_start==null) diff --git a/cache/include/javascript/sugar_grp_quickcomp.js b/cache/include/javascript/sugar_grp_quickcomp.js index 5670ede7..6dd482d0 100644 --- a/cache/include/javascript/sugar_grp_quickcomp.js +++ b/cache/include/javascript/sugar_grp_quickcomp.js @@ -33,8 +33,7 @@ function method_callback(o){var resp=YAHOO.lang.JSON.parse(o.responseText),reque reqid=global_request_registry[request_id];if(typeof(reqid)!='undefined'){widget=global_request_registry[request_id][0];method_name=global_request_registry[request_id][1];widget[method_name](result);}} SugarClass.inherit("SugarVCalClient","SugarClass");function SugarVCalClient(){this.init();} SugarVCalClient.prototype.init=function(){} -SugarVCalClient.prototype.load=function(user_id,request_id){this.user_id=user_id;var vcal_server='./vcal_server.php?type=vfb&source=outlook&user_id='+user_id;if(typeof(window.combo_date_start)!='undefined'){var date_start=window.combo_date_start.datetime;vcal_server+='&datestart='+date_start;} -YAHOO.util.Connect.asyncRequest('GET',vcal_server,{success:function(result){if(typeof GLOBAL_REGISTRY.freebusy=='undefined'){GLOBAL_REGISTRY.freebusy=new Object();} +SugarVCalClient.prototype.load=function(user_id,request_id){this.user_id=user_id;YAHOO.util.Connect.asyncRequest('GET','./vcal_server.php?type=vfb&source=outlook&user_id='+user_id,{success:function(result){if(typeof GLOBAL_REGISTRY.freebusy=='undefined'){GLOBAL_REGISTRY.freebusy=new Object();} if(typeof GLOBAL_REGISTRY.freebusy_adjusted=='undefined'){GLOBAL_REGISTRY.freebusy_adjusted=new Object();} GLOBAL_REGISTRY.freebusy[user_id]=SugarVCalClient.prototype.parseResults(result.responseText,false);GLOBAL_REGISTRY.freebusy_adjusted[user_id]=SugarVCalClient.prototype.parseResults(result.responseText,true);global_request_registry[request_id][0].display();},failure:function(result){this.success(result);},argument:{result:result}});} SugarVCalClient.prototype.parseResults=function(textResult,adjusted){var match=/FREEBUSY.*?\:([\w]+)\/([\w]+)/g;var result;var timehash=new Object();var dst_start;var dst_end;if(GLOBAL_REGISTRY.current_user.fields.dst_start==null) diff --git a/data/BeanFactory.php b/data/BeanFactory.php index fe2c1387..2fb34a7a 100644 --- a/data/BeanFactory.php +++ b/data/BeanFactory.php @@ -54,14 +54,26 @@ class BeanFactory { * Returns a SugarBean object by id. The Last 10 loaded beans are cached in memory to prevent multiple retrieves per request. * If no id is passed, a new bean is created. * @static - * @param String $module + * @param String $module * @param String $id - * @param Bool $encode @see SugarBean::retrieve + * @param Array $params A name/value array of parameters. Names: encode, deleted, + * If $params is boolean we revert to the old arguments (encode, deleted), and use $params as $encode. + * This will be changed to using only $params in later versions. * @param Bool $deleted @see SugarBean::retrieve * @return SugarBean */ - public static function getBean($module, $id = null, $encode = true, $deleted = true) + public static function getBean($module, $id = null, $params = array(), $deleted = true) { + + // Check if params is an array, if not use old arguments + if (isset($params) && !is_array($params)) { + $params = array('encode' => $params); + } + + // Pull values from $params array + $encode = isset($params['encode']) ? $params['encode'] : true; + $deleted = isset($params['deleted']) ? $params['deleted'] : $deleted; + if (!isset(self::$loadedBeans[$module])) { self::$loadedBeans[$module] = array(); self::$touched[$module] = array(); diff --git a/data/Link2.php b/data/Link2.php index c7e337a5..f0a331ac 100644 --- a/data/Link2.php +++ b/data/Link2.php @@ -531,7 +531,8 @@ class Link2 { */ protected function getRelatedBean($id = false) { - return BeanFactory::getBean($this->getRelatedModuleName(), $id); + $params = array('encode' => true, 'deleted' => true); + return BeanFactory::getBean($this->getRelatedModuleName(), $id, $params); } public function &__get($name) diff --git a/data/Relationships/One2MBeanRelationship.php b/data/Relationships/One2MBeanRelationship.php index d144e5e8..f858fb37 100644 --- a/data/Relationships/One2MBeanRelationship.php +++ b/data/Relationships/One2MBeanRelationship.php @@ -315,14 +315,29 @@ class One2MBeanRelationship extends One2MRelationship $alias = $GLOBALS['db']->getValidDBName($alias, false, 'alias'); $tableInRoleFilter = ""; - if ($targetTable == "meetings" && $linkIsLHS == false) { - if ($alias == "meetings_activities_1_meetings_rel" || - $alias == "meetings_activities_1_tasks_rel" || - $alias == "meetings_activities_1_calls_rel" || - $alias == "meetings_activities_1_emails_rel" || - $alias == "meetings_activities_1_notes_rel") + if (($targetTable == "meetings" || + $targetTable == "notes" || + $targetTable == "tasks" || + $targetTable == "calls") && $linkIsLHS == false) { + if (substr($alias, -25) == "activities_1_meetings_rel" || + substr($alias, -22) == "activities_1_tasks_rel" || + substr($alias, -22) == "activities_1_calls_rel" || + substr($alias, -23) == "activities_1_emails_rel" || + substr($alias, -22) == "activities_1_notes_rel") $tableInRoleFilter = $alias; } + else if (($startingTable == "meetings" || + $startingTable == "notes" || + $startingTable == "tasks" || + $startingTable == "calls" || + $startingTable == "emails") && empty($linkIsLHS)) { + if (substr($alias, -23) == "activities_meetings_rel" || + substr($alias, -20) == "activities_tasks_rel" || + substr($alias, -20) == "activities_calls_rel" || + substr($alias, -21) == "activities_emails_rel" || + substr($alias, -20) == "activities_notes_rel") + $tableInRoleFilter = $startingTable; + } //Set up any table aliases required $targetTableWithAlias = "$targetTable $alias"; diff --git a/data/Relationships/One2MRelationship.php b/data/Relationships/One2MRelationship.php index 2d99a06c..3a82efa0 100644 --- a/data/Relationships/One2MRelationship.php +++ b/data/Relationships/One2MRelationship.php @@ -121,9 +121,17 @@ class One2MRelationship extends M2MRelationship public function add($lhs, $rhs, $additionalFields = array()) { $dataToInsert = $this->getRowToInsert($lhs, $rhs, $additionalFields); + //If the current data matches the existing data, don't do anything if (!$this->checkExisting($dataToInsert)) { + // Pre-load the RHS relationship, which is used later in the add() function and expects a Bean + // and we also use it for clearing relationships in case of non self-referencing O2M relations + // (should be preloaded because when using the relate_to field for updating/saving relationships, + // only the bean id is loaded into $rhs->$rhsLinkName) + $rhsLinkName = $this->rhsLink; + $rhs->load_relationship($rhsLinkName); + // If it's a One2Many self-referencing relationship // the positions of the default One (LHS) and Many (RHS) are swaped // so we should clear the links from the many (left) side @@ -144,12 +152,10 @@ class One2MRelationship extends M2MRelationship foreach($related as $relBean) { $this->remove($focus, $relBean); } - } else { // For non self-referencing, just load the many (RHS) side, and remove all the relationships from it - $rhsLinkName = $this->rhsLink; - //In a one to many, any existing links from the many (right) side must be removed first - $rhs->load_relationship($rhsLinkName); + } else { // For non self-referencing, remove all the relationships from the many (RHS) side $this->removeAll($rhs->$rhsLinkName); } + // Add relationship parent::add($lhs, $rhs, $additionalFields); } diff --git a/data/SugarBean.php b/data/SugarBean.php index bddde7b4..216de980 100644 --- a/data/SugarBean.php +++ b/data/SugarBean.php @@ -270,7 +270,12 @@ class SugarBean * @var array */ protected $loaded_relationships = array(); - + + /** + * set to true if dependent fields updated + */ + protected $is_updated_dependent_fields = false; + /** * Constructor for the bean, it performs following tasks: * @@ -2138,7 +2143,8 @@ function save_relationship_changes($is_update, $exclude=array()) { $this->custom_fields->fill_relationships(); } - + + $this->is_updated_dependent_fields = false; $this->fill_in_additional_detail_fields(); $this->fill_in_relationship_fields(); //make a copy of fields in the relationship_fields array. These field values will be used to @@ -2454,6 +2460,8 @@ function save_relationship_changes($is_update, $exclude=array()) $row_offset = 0, $limit=-1, $max=-1, $show_deleted = 0) { global $layout_edit_mode; + $query_array = array(); + if(isset($layout_edit_mode) && $layout_edit_mode) { $response = array(); @@ -2472,7 +2480,18 @@ function save_relationship_changes($is_update, $exclude=array()) } $this->load_relationship($related_field_name); - $query_array = $this->$related_field_name->getQuery(true); + + if ($this->$related_field_name instanceof Link) { + + $query_array = $this->$related_field_name->getQuery(true); + } else { + + $query_array = $this->$related_field_name->getQuery(array( + "return_as_array" => true, + 'where' => '1=1' // hook for 'where' clause in M2MRelationship file + )); + } + $entire_where = $query_array['where']; if(!empty($where)) { @@ -2717,7 +2736,11 @@ function save_relationship_changes($is_update, $exclude=array()) $query_array = $subquery['query_array']; $select_position=strpos($query_array['select'],"SELECT"); $distinct_position=strpos($query_array['select'],"DISTINCT"); - if ($select_position !== false && $distinct_position!= false) + if (!empty($subquery['params']['distinct']) && !empty($subpanel_def->table_name)) + { + $query_rows = "( SELECT count(DISTINCT ". $subpanel_def->table_name . ".id)". $subquery['from_min'].$query_array['join']. $subquery['where'].' )'; + } + elseif ($select_position !== false && $distinct_position!= false) { $query_rows = "( ".substr_replace($query_array['select'],"SELECT count(",$select_position,6). ")" . $subquery['from_min'].$query_array['join']. $subquery['where'].' )'; } @@ -4476,7 +4499,6 @@ function save_relationship_changes($is_update, $exclude=array()) function list_view_parse_additional_sections(&$list_form) { } - /** * Assigns all of the values into the template for the list view */ @@ -4485,7 +4507,6 @@ function save_relationship_changes($is_update, $exclude=array()) static $cache = array(); // cn: bug 12270 - sensitive fields being passed arbitrarily in listViews $sensitiveFields = array('user_hash' => ''); - $return_array = Array(); global $app_list_strings, $mod_strings; @@ -4548,9 +4569,10 @@ function save_relationship_changes($is_update, $exclude=array()) /** * Construct where clause from a list of name-value pairs. * @param array $fields_array Name/value pairs for column checks + * @param boolean $deleted Optional, default true, if set to false deleted filter will not be added. * @return string The WHERE clause */ - function get_where($fields_array) + function get_where($fields_array, $deleted=true) { $where_clause = ""; foreach ($fields_array as $name=>$value) @@ -4563,9 +4585,13 @@ function save_relationship_changes($is_update, $exclude=array()) $where_clause .= "$name = ".$this->db->quoted($value,false); } if(!empty($where_clause)) { - return "WHERE $where_clause AND deleted=0"; + if($deleted) { + return "WHERE $where_clause AND deleted=0"; + } else { + return "WHERE $where_clause"; + } } else { - return "WHERE deleted=0"; + return ""; } } @@ -4576,11 +4602,12 @@ function save_relationship_changes($is_update, $exclude=array()) * Internal function, do not override. * @param array @fields_array array of name value pairs used to construct query. * @param boolean $encode Optional, default true, encode fetched data. + * @param boolean $deleted Optional, default true, if set to false deleted filter will not be added. * @return object Instance of this bean with fetched data. */ - function retrieve_by_string_fields($fields_array, $encode=true) + function retrieve_by_string_fields($fields_array, $encode=true, $deleted=true) { - $where_clause = $this->get_where($fields_array); + $where_clause = $this->get_where($fields_array, $deleted); if(isset($this->custom_fields)) $custom_join = $this->custom_fields->getJOIN(); else $custom_join = false; @@ -4614,6 +4641,7 @@ function save_relationship_changes($is_update, $exclude=array()) $row = $this->convertRow($row); $this->fetched_row = $row; $this->fromArray($row); + $this->is_updated_dependent_fields = false; $this->fill_in_additional_detail_fields(); return $this; } diff --git a/download.php b/download.php index 13d28f62..85e35c76 100644 --- a/download.php +++ b/download.php @@ -177,19 +177,10 @@ else { header("Content-Type: image/png"); } } else { - - if(preg_match("/\.jpg|\.gif|\.png|\.jpeg/i", $name)){ - $mime = getimagesize($download_location); - if(!empty($mime)) { - header("Content-Type: {$mime['mime']}"); - } - } - else{ - header("Content-Type: application/force-download"); - header("Content-type: application/octet-stream"); - header("Content-Disposition: attachment; filename=\"".$name."\";"); - } + header("Content-Type: application/force-download"); + header("Content-type: application/octet-stream"); + header("Content-Disposition: attachment; filename=\"".$name."\";"); } // disable content type sniffing in MSIE header("X-Content-Type-Options: nosniff"); diff --git a/files.md5 b/files.md5 index 06d6a5ba..e442a900 100644 --- a/files.md5 +++ b/files.md5 @@ -1,5 +1,5 @@ 'd3f150e4a5bed444763ebe8a81742a95', './.htaccess' => 'd41d8cd98f00b204e9800998ecf8427e', @@ -49,7 +49,7 @@ $md5_string = array ( './include/SugarObjects/templates/issue/language/en_us.lang.php' => '01125f95956706630ee7f27233e6d75a', './include/SugarObjects/templates/issue/language/application/en_us.lang.php' => '1e7759c750b218ade41325c56d23dbd5', './include/SugarObjects/templates/company/config.php' => 'a9b4d6ee2c4a4d3b40194db8d3696ff3', - './include/SugarObjects/templates/company/vardefs.php' => '502c731b68560bb1a1b6bb3f8632cf73', + './include/SugarObjects/templates/company/vardefs.php' => '3b2dce514f71aeb8a1e53bf7b4100b31', './include/SugarObjects/templates/company/icons/company_32.gif' => 'eb850fc1863a46987cdafca12693c789', './include/SugarObjects/templates/company/icons/company.gif' => '7890367dfe0e337a2f5f2839b3e6dac7', './include/SugarObjects/templates/company/icons/Createcompany.gif' => '3978b32e01cbeb974d86b1da0617dae9', @@ -67,7 +67,7 @@ $md5_string = array ( './include/SugarObjects/templates/company/language/en_us.lang.php' => 'c9a98e5acc779109f500d30bc291fb65', './include/SugarObjects/templates/company/language/application/en_us.lang.php' => '959d9ce9f8538ed0b9c304df6ab0275c', './include/SugarObjects/templates/person/config.php' => '03a311c5d9412313a2c81bbf607781bd', - './include/SugarObjects/templates/person/vardefs.php' => '1ce92da11d18bde270d018f16f906e30', + './include/SugarObjects/templates/person/vardefs.php' => 'a4df1bb6a062d549b9ceda8d8162cb0c', './include/SugarObjects/templates/person/icons/person.gif' => 'ea5e2b2022166291d01ccedaf24b4e33', './include/SugarObjects/templates/person/icons/person_32.gif' => '1550c24a793910550200679be1c5c078', './include/SugarObjects/templates/person/icons/Createperson.gif' => '2e20692d501b15729294b80f4f311d77', @@ -277,7 +277,7 @@ $md5_string = array ( './include/SubPanel/SubPanelDynamic.html' => '4f74fcd4211256ec95d0054799608906', './include/SubPanel/tpls/singletabmenu.tpl' => '252c751fac27affd042dc7ba1ee83a00', './include/SubPanel/SubPanelDefinitions.php' => '78199f5f0bfe90e1fb1c76afe776e72d', - './include/SubPanel/SubPanelTiles.php' => '846a7239e5d40b60e8e611c443db6aaf', + './include/SubPanel/SubPanelTiles.php' => 'b14a0f1af9988518b632a0f815d291ce', './include/SubPanel/registered_layout_defs.php' => 'd71c8000fd9dabffa19a3711f60c0f39', './include/SubPanel/SubPanelViewer.php' => 'de240547489fe04b229caa2c5fc34e61', './include/SubPanel/SubPanel.php' => '22713e2b27e94ce43af75048b4694394', @@ -293,7 +293,7 @@ $md5_string = array ( './include/Sugarpdf/sugarpdf_default.php' => '7f19994bcf11b5d98801c3739eab57a2', './include/Sugarpdf/sugarpdf_config.php' => '3768422dd5bfb14aca352ea209a0ebae', './include/clean.php' => 'e95a4b6caeb54b3064cda0c7748dd3be', - './include/externalAPI/ExternalAPIFactory.php' => 'bf19d1488383255a10e1c399529c5e5d', + './include/externalAPI/ExternalAPIFactory.php' => '0dfa0647b6b6484f28927eb5018749e0', './include/externalAPI/cmis_repository_wrapper.php' => 'ff3bb54e2abd73334bb05df8b6920b8d', './include/externalAPI/Base/WebDocument.php' => 'ede22580002f6416a2502dee7d0be18f', './include/externalAPI/Base/OAuthPluginBase.php' => 'd552b49c445defdc9007389cb90e931b', @@ -404,7 +404,7 @@ $md5_string = array ( './include/SugarFields/Fields/Base/InlineEditView.tpl' => '8ae00593c64a7c5171a9f4f463cbb1d3', './include/SugarFields/Fields/Base/SearchForm.tpl' => '89584f42f6317bd59182cf6aa8cc0763', './include/SugarFields/Fields/Base/DetailView.tpl' => '0862eead55f684a00a978662cedca828', - './include/SugarFields/Fields/Base/SugarFieldBase.php' => '3bffbac5971d7e36f7b80fa31d52e453', + './include/SugarFields/Fields/Base/SugarFieldBase.php' => '1745920fda4cd44a700128ef99929b71', './include/SugarFields/Fields/Base/EditViewFunction.tpl' => 'cc97e23ed4bc84c8bf7bdfad700a1371', './include/SugarFields/Fields/Base/EditView.tpl' => 'b6ac28598bf744bb907e12e420368501', './include/SugarFields/Fields/Base/ListView.tpl' => 'e5bef5e195aad2fb3fa6c1ae93c8bcca', @@ -424,6 +424,8 @@ $md5_string = array ( './include/SugarFields/Fields/Assigned_user_name/SugarFieldAssigned_user_name.php' => '57e6fa57d7b1c109fd276a047c4dc0b1', './include/SugarFields/Fields/Assigned_user_name/SearchView.tpl' => 'e6949bbc092460af32c5c108be011cd4', './include/SugarFields/Fields/Multienum/DetailView.tpl' => '6e2d1bcc30258e5ae66ba5a0c0adb7d4', + './include/SugarFields/Fields/Multienum/WirelessDetailView.tpl' => '7044c39f90dea4f1d6b5dc7043205f1a', + './include/SugarFields/Fields/Multienum/WirelessEditView.tpl' => '25a63f0d714fe39a885ca125c430ccea', './include/SugarFields/Fields/Multienum/EditViewFunction.tpl' => '95ba0af2ce15b8c3372cde1746392a41', './include/SugarFields/Fields/Multienum/EditView.tpl' => 'bf916ff2f686bf8e809a22076f49dae7', './include/SugarFields/Fields/Multienum/SugarFieldMultienum.php' => 'dd429ba718e4975dbdc023f038ff6763', @@ -474,14 +476,14 @@ $md5_string = array ( './include/SugarCharts/swf/chart.swf' => 'afda6fe91342c4864d1991d3c1ccbfff', './include/SugarCharts/swf/groupByChart.swf' => '2eca03fe41128001349bacf997b1fedc', './include/SugarCharts/SugarChartFactory.php' => '4873cc48dd3a2258af3a7998713b2398', - './include/SugarCharts/JsChart.php' => '7b9cc434a65f3551fcd87d3f85262de5', - './include/SugarCharts/SugarChart.php' => '2a4c44bac5f8b760705e2830903e1743', + './include/SugarCharts/JsChart.php' => '64c1b3c0eaab3527751574a4b6d91c6c', + './include/SugarCharts/SugarChart.php' => 'b7e886ffcb138fe982de53cbdf508bef', './include/SugarCharts/Jit/js/sugarCharts.js' => '643ed60792a2efe2c62c6ee3f094d735', './include/SugarCharts/Jit/js/mySugarCharts.js' => '6b3dd85fe7c6d5714b6d12c63e536982', './include/SugarCharts/Jit/js/Jit/jit.js' => 'a9f9f3efa0c6d7af942edbd3cddf9833', './include/SugarCharts/Jit/tpls/chart.tpl' => '035936b0a337a1b52edccffcd6e44e65', './include/SugarCharts/Jit/tpls/DashletGenericChartScript.tpl' => '2c4808cf07078a03c669b52ab5f6997a', - './include/SugarCharts/Jit/JitReports.php' => '2ea46bce40c7b654e4d9b9108278ecfd', + './include/SugarCharts/Jit/JitReports.php' => '3a8e246da525fb36ffe1fd49447d4103', './include/SugarCharts/Jit/FlashCanvas/flashcanvas.js' => 'c2300996439f4a33c849f40afc5da8ae', './include/SugarCharts/Jit/FlashCanvas/canvas2png.js' => '71a23466955e17ab3094233fee8db708', './include/SugarCharts/Jit/FlashCanvas/flashcanvas.swf' => '528d82bb81799f23d4def3425badf913', @@ -505,7 +507,7 @@ $md5_string = array ( './include/utils/php_zip_utils.php' => '837fa2513561b0b259abbbbd4082cd7e', './include/utils/zip_utils.php' => 'f765a38da8ded7c908fa5319d175c836', './include/utils/mvc_utils.php' => '5de721ef6ef949ccc21b17bfeec26356', - './include/utils/layout_utils.php' => '2a581d3954deea35b6fa3f88e9804e4f', + './include/utils/layout_utils.php' => '9f6097ddf3030e9a1c7a63457aeb4f0e', './include/images/install_themes.jpg' => '01fe7a67fb311afe5e93e9819ca36b12', './include/images/seed_jim_id.gif' => 'ccdaf0d492f924e8af2611b374550abd', './include/images/docs.png' => '0752db044e772d50293561053acac995', @@ -538,6 +540,10 @@ $md5_string = array ( './include/images/poweredby_sugarcrm_65.png' => '1eca46a677f05127610b2e1532ba58ab', './include/images/kb.png' => 'c2ca9ff53826ae025ea68f861957dcc9', './include/images/sugar_md_open.png' => 'b16339fb0a08fc2b35ba9d7d811bfb69', + './include/images/tour/FirstFrame.png' => 'd1b2fca94b47090e42b075ba14fd671f', + './include/images/tour/arrow_ie.png' => 'fbb700a88eb3591ccfb8a0fa3b57c238', + './include/images/tour/arrow.png' => '4fb216732f51fe951466acaebc523a8a', + './include/images/tour/profile_link.png' => '1b9fed9892a03f52d52d493ee7e1519b', './include/images/1.gif' => '9560abd50536d3d57c23316c75f93fe7', './include/images/powered_by_sugarcrm.gif' => 'fbc4de76cab648346bd7273823e0a0e2', './include/images/cube_bg.gif' => 'bb01880551373dc9a2056697be69e5c1', @@ -572,35 +578,39 @@ $md5_string = array ( './include/nusoap/license.txt' => '25823f4a2e463ab2c6b5873f07e428e1', './include/nusoap/class.wsdl.php' => 'cd7f1a43ca08891ac1ce04d4d1282c49', './include/nusoap/class.soap_val.php' => '084a898ecf261c201427fd41d4ee40e0', - './include/utils.php' => '0e9d69bfddcf81c81a4ca9c6aa68bbc9', + './include/utils.php' => '87619e6f38a183a132596606fa5c16fb', './include/SugarHttpClient.php' => '87fa99a397caaaceb121a21d91ed5260', './include/Sugar_Smarty.php' => 'ac140125309e194a7f43747d41417cd4', - './include/phpmailer/class.smtp.php' => '64255208cd6f263a69d58918dcb7138d', - './include/phpmailer/README' => '9522b5930919ec251b6f4edda0584480', - './include/phpmailer/license.txt' => '278f2557e3b277b94e9a8430f6a6d0a9', - './include/phpmailer/language/phpmailer.lang-pl.php' => '72d18cb4146127e89db0a402fb18e10d', - './include/phpmailer/language/phpmailer.lang-de.php' => 'b825169df27b56b0592992f13d6eeecb', - './include/phpmailer/language/phpmailer.lang-ru.php' => '1ba9cde2e2ad42a3f367bc3ffa070342', - './include/phpmailer/language/phpmailer.lang-tr.php' => '7ddc04019a3ab315429a01d1eac1ac10', - './include/phpmailer/language/phpmailer.lang-ro.php' => 'cba42902cc751ea7e80720e5ba6b9d1a', - './include/phpmailer/language/phpmailer.lang-dk.php' => 'e3bebecccdbd1b7b07f32989d44420f1', - './include/phpmailer/language/phpmailer.lang-nl.php' => '69c2fb42974c0e5046c83182238608b3', - './include/phpmailer/language/phpmailer.lang-ja.php' => '0a79142a326c7f23f4ebcac251b9a1e2', - './include/phpmailer/language/phpmailer.lang-et.php' => '50e92cd6a80d425bf79b0347b27c7364', - './include/phpmailer/language/phpmailer.lang-no.php' => '60a01ff00af72c21a9afa8b906cb160a', + './include/phpmailer/extras/htmlfilter.php' => '4d5143899340a690d41a4959428ea674', + './include/phpmailer/LICENSE' => '278f2557e3b277b94e9a8430f6a6d0a9', + './include/phpmailer/class.smtp.php' => 'fd00211692e65984f97f2e4820bd6302', + './include/phpmailer/README' => '5a77656de86a8d65fe03fad7f851534f', + './include/phpmailer/language/phpmailer.lang-pl.php' => '3933cfa44296e3c3e41b8fe8bf89092c', + './include/phpmailer/language/phpmailer.lang-de.php' => 'be8f19de5d7a12568066fb04e7feeb8c', + './include/phpmailer/language/phpmailer.lang-ru.php' => 'b7ed33812e39d722df735dc4f11ec660', + './include/phpmailer/language/phpmailer.lang-tr.php' => '8706743bc477210606ddedfbd4c03af3', + './include/phpmailer/language/phpmailer.lang-ch.php' => '68d79d6467a003fa41672a5690d9eae3', + './include/phpmailer/language/phpmailer.lang-ro.php' => 'a87ff3c8cc2d438c0d4ca1efd3340d33', + './include/phpmailer/language/phpmailer.lang-dk.php' => 'b889d351c4ed834ff2566be55c7d2a40', + './include/phpmailer/language/phpmailer.lang-nl.php' => 'a31febd0f5ce0f8c9ea3a1487fb90343', + './include/phpmailer/language/phpmailer.lang-ja.php' => '5633923d2fe9b4a4c91cdc6f645cd2e3', + './include/phpmailer/language/phpmailer.lang-et.php' => '59ec530db72bdf3c929cbced24d84f1f', + './include/phpmailer/language/phpmailer.lang-no.php' => '4bce15e32912f1b60c1d4e539e258a6d', './include/phpmailer/language/phpmailer.lang-en.php' => '50e6e86986c7f547b7e1e4406eb6b54b', - './include/phpmailer/language/phpmailer.lang-se.php' => '3c06baba1b6ab4d8acf0602cd7e3700a', - './include/phpmailer/language/phpmailer.lang-hu.php' => '49bdceec325435adae3b5f9c4d3f86de', - './include/phpmailer/language/phpmailer.lang-fr.php' => 'c693b4a9214c28fe10c65072833e5bd7', - './include/phpmailer/language/phpmailer.lang-cz.php' => '71777a5d541217d10f85bdd3ee09f3c9', - './include/phpmailer/language/phpmailer.lang-es.php' => '84174963798d08a7ccdc4ca9c969e3d6', - './include/phpmailer/language/phpmailer.lang-fi.php' => '1d0b14ace9b7c075be51756462fdcbd7', - './include/phpmailer/language/phpmailer.lang-it.php' => '6d9025ba4f6b9dbe9bbf0044f77f407c', - './include/phpmailer/language/phpmailer.lang-fo.php' => '19c5f009920dff72a02675dad3c6c749', - './include/phpmailer/language/phpmailer.lang-ar.php' => '007791fbed48cbc28248a543e023ddbf', - './include/phpmailer/language/phpmailer.lang-ca.php' => '228a8e6e6eb5fee58942f5d0740314ce', - './include/phpmailer/language/phpmailer.lang-br.php' => 'd294ef50bd7d57e70e866a7618528048', - './include/phpmailer/class.phpmailer.php' => 'a78d163362a44ff475e9141c3c75ed99', + './include/phpmailer/language/phpmailer.lang-zh.php' => '826f3a6e03f3d475065ec3b4b9f765f0', + './include/phpmailer/language/phpmailer.lang-se.php' => '9f8db6e50c0fcfa53ee2c810e604439b', + './include/phpmailer/language/phpmailer.lang-hu.php' => '06137884e974504647606c12c403ef94', + './include/phpmailer/language/phpmailer.lang-fr.php' => '35824828ce4dee7486e2ebddc8c90b54', + './include/phpmailer/language/phpmailer.lang-cz.php' => '2420cdfa4b0b35142d79ff02a2197520', + './include/phpmailer/language/phpmailer.lang-es.php' => 'bb915fc8e902a08d7f5de070c023c4cd', + './include/phpmailer/language/phpmailer.lang-fi.php' => '029e5ade41d5ae5dcc7f1869c0e85141', + './include/phpmailer/language/phpmailer.lang-zh_cn.php' => '8896e3cb067525faf5526287e7c62efe', + './include/phpmailer/language/phpmailer.lang-it.php' => 'e58eb12280851b2b634480b0eb16cfa9', + './include/phpmailer/language/phpmailer.lang-fo.php' => '081059e68c63e095c7584f250232ea2a', + './include/phpmailer/language/phpmailer.lang-ar.php' => '646c785bc6a11f13671a59ea62a8cdb1', + './include/phpmailer/language/phpmailer.lang-ca.php' => 'd62aa6dcbbf9922a0ff5b3157493d34f', + './include/phpmailer/language/phpmailer.lang-br.php' => 'a1364ab381ebdf3f05999b31bada24bd', + './include/phpmailer/class.phpmailer.php' => '2252f7b9a03504be7c83d0ea7997bff4', './include/php-sql-parser.php' => '4fd316e1251bd1134a46134ad7ddaf57', './include/database/DBManager.php' => '9a60fc7b5ac377121f8817b617c566e9', './include/database/MysqlHelper.php' => '6081c98891b401e3653bde7ec539b6d9', @@ -612,7 +622,7 @@ $md5_string = array ( './include/database/MssqlHelper.php' => '6b3a36ab4462e0f838c35e0e74e0f02b', './include/database/DBManagerFactory.php' => '021c6c562cd96f304544af0e336dc736', './include/database/SqlsrvManager.php' => '4a3d6c5e56ae8fe5fdb07ead522c324e', - './include/database/MssqlManager.php' => 'b7090f5ff68358bdf040bb1b979e54b9', + './include/database/MssqlManager.php' => 'b671c14e37f76ddf22f22fcb9e1889da', './include/timezone/timezones.php' => '15844342704f03ef8d40603abe9aa99b', './include/SugarSQLValidate.php' => 'eb288af9ccb9828370ef3999ad926619', './include/connectors/ConnectorFactory.php' => '33d27fc539bbd684cf7deb0cea6ed37d', @@ -642,7 +652,7 @@ $md5_string = array ( './include/templates/TemplateDragDropChooser.php' => '312be77f2351b29f7e79bf416ddd8772', './include/templates/Template.php' => '36ef9b944d7e36d9853d9879f6194969', './include/templates/TemplateGroupChooser.php' => '6ae99e0ff3795b613d03ec0474e52c46', - './include/TemplateHandler/TemplateHandler.php' => 'a8d26ccbe311238a6c52674d51470a4d', + './include/TemplateHandler/TemplateHandler.php' => '2c70ff6e5927aeedf93da151b9124397', './include/SugarTheme/SugarTheme.php' => 'cf9766ea68d6faab44025adde04320b6', './include/SugarTheme/getImage.php' => '0cdce763d79863dcdfc6b9e1b13a3516', './include/SugarTheme/SugarSprites.php' => '10818287a033eed727e4269522cc7044', @@ -651,7 +661,7 @@ $md5_string = array ( './include/SugarDependentDropdown/javascript/SugarDependentDropdown.js' => '4d077b3991c83098e4bca166bc715071', './include/SugarDependentDropdown/SugarDependentDropdown.php' => '86eb13e7c54068ec87679e98a4e0d406', './include/export_utils.php' => '885a0dd6cda051658520a90f522f787f', - './include/globalControlLinks.php' => '7bb7851575077b76cc686c8f69929789', + './include/globalControlLinks.php' => 'dfa767d1960f89fddeea3f519cf3427f', './include/SugarTinyMCE.php' => 'a00a969d2a2df9dbbc80ead4af9b40de', './include/tabs.php' => '7cf9418691424c673218c535fec27a05', './include/SugarOAuthServer.php' => '2213c81d7cef1884997b4a0d38216fd9', @@ -726,17 +736,19 @@ $md5_string = array ( './include/ytree/TreeView/css/check/tree.css' => '0eb57b9c70f75ca706fbab4e29ac2ad7', './include/ytree/TreeView/css/forecasts/tree.css' => '59797a1f43dc5602932f826d687d398f', './include/GroupedTabs/GroupedTabStructure.php' => '9b88d71d41cb5beb67e5a7344101f537', + './include/EditView/Panels.js' => 'ba21e9a68e1025858f7b2276629eef66', './include/EditView/SubpanelQuickCreate.php' => 'd57a15fb747f7247f2b9d77cd86064be', './include/EditView/footer.tpl' => '8bef7a56d0a1413d935094347ef96538', - './include/EditView/SugarVCR.php' => '6a0a3aaddb7889a8d618a4aede4d6d90', - './include/EditView/header.tpl' => 'a784dee4bebb0dca1239e26ec927a264', + './include/EditView/SugarVCR.php' => '06f3b74170c2854269ea410d99e997a3', + './include/EditView/header.tpl' => '1851218e36edd4d98fdbb803a2f79977', './include/EditView/QuickCreate.tpl' => 'fa3dacaca4c4985fa7d4e19e44d8a30a', './include/EditView/EditView.php' => '585450ac1a175834d05e944f77364c17', - './include/EditView/EditView2.php' => '3ea04ba5587d3af157c4d425e19f246c', + './include/EditView/EditView2.php' => '701cb0edc2ded8ad06c9df64efea3788', './include/EditView/PopupQuickCreate.php' => '9a8b7a895799ed90058b3e070ad7f672', - './include/EditView/EditView.tpl' => '5b4cda504eee219faaf08af37af191c1', + './include/EditView/SugarVCR.tpl' => '5b46cb6d983f213ec90733aa54bfba45', + './include/EditView/EditView.tpl' => 'fe408b4bea39633daf1025738f1f4b4e', './include/EditView/QuickCreate.php' => 'a4351f400593c2a1933176d8e34bc82c', - './include/EditView/SubpanelQuickEdit.php' => '04bf7a6aea0f3866a56cfca4d7b558a4', + './include/EditView/SubpanelQuickEdit.php' => 'fffaf282dad4779c25d5296e64d5c900', './include/SugarQueue/SugarCronJobs.php' => 'd7b547d698238a2bd170c86ce3ed67e1', './include/SugarQueue/SugarCronRemoteJobs.php' => '8a30786e408efd58067d73d0acb630f9', './include/SugarQueue/SugarJobQueue.php' => '13f33437bb20259ce088c020cc7839dd', @@ -788,14 +800,16 @@ $md5_string = array ( './include/javascript/sugar_yui_overrides.js' => '2044e4ff54670e82359c21cca12b2dd5', './include/javascript/cookie.js' => '88a6745e90f7c043394eca8b106068b2', './include/javascript/popup_parent_helper.js' => '592953cb14307a0ce288261d40c4f8a9', - './include/javascript/sugar_3.js' => '853a96a821de7a2e0b0850bf49eabc87', + './include/javascript/sugar_3.js' => '21774b3305dca7717e679098d3f2f0bd', './include/javascript/jquery.js' => '819fb9d29c24f79d34343e9f182aaf24', './include/javascript/sugar_connection_event_listener.js' => '27234843e68e64fc9c399044619320be', - './include/javascript/jsclass_async.js' => 'ee2946c0fbf3d8f941657be6bd1b6c9c', + './include/javascript/jsclass_async.js' => 'd725c16df9803e561437c4a2e13d1372', './include/javascript/quickCompose.js' => '43694b8ad631b58dd9030925a99f5a15', './include/javascript/menu.js' => '1ee25f32c6da30d39facf4e8ccbce531', + './include/javascript/tour.js' => '450526b4bfa1c0f9bc4980b00fc8e9ee', './include/javascript/importWizard.js' => '181b53a6248a2b8db6cf03cd2c4c2c66', './include/javascript/jsclass_base.js' => 'f3375a1e38ada7c4bdd1b498c9993cc3', + './include/javascript/jquery/jquery.popoverext.js' => 'd8f03476467cfffc7b91e31ed4f2383b', './include/javascript/jquery/markitup/sets/default/style.css' => '32f0c48dbf650d79461a66b83b21f485', './include/javascript/jquery/markitup/sets/default/images/stroke.png' => 'cf25f036aa3d24212a3191b04a0b4024', './include/javascript/jquery/markitup/sets/default/images/link.png' => 'a5dc8319bff018855ee0441e4a3b54b9', @@ -819,8 +833,10 @@ $md5_string = array ( './include/javascript/jquery/jquery.elementReady.js' => 'ca3ff36ea735918a7425a47940d0e1c8', './include/javascript/jquery/jquery.js' => '219073097031d9c1a95a1291d66f3a10', './include/javascript/jquery/jquery.tipTip.js' => '3bcfb8155251dc38fe2d965e8ff78408', + './include/javascript/jquery/bootstrap.min.js' => '5eb1cb055ddcf2f7b2b662f73f56cf1f', './include/javascript/jquery/jquery.highLight.js' => '336cc69cbf2b83a81e12b150ed6c603d', './include/javascript/jquery/jquery.json-2.3.js' => '761234abe4fbf042f3f8396ec4502e48', + './include/javascript/jquery/jquery.effects.custombounce.js' => 'bee3ef7f90fea5a7caaf4a5b0268efdf', './include/javascript/jquery/jquery.hotkeys.js' => '7c65a13a5952af03968c0f92e1de8cce', './include/javascript/jquery/jquery-ui-min.js' => '9f94b177db651a5d4a71682fe0ea04b7', './include/javascript/jquery/jquery-min.js' => '4bab8348a52d17428f684ad1ec3a427e', @@ -2584,7 +2600,7 @@ $md5_string = array ( './include/SearchForm/tpls/SearchFormGeneric.tpl' => '2e5f84f3de4d7e15d122e57253acfa91', './include/SearchForm/SugarSpot.php' => 'a899046092d8a1bdb1fd93352b209ab4', './include/SearchForm/SearchForm.php' => '37a79061b1ef9fc6be0ada54cf4b9a9b', - './include/SearchForm/SearchForm2.php' => '546d9c9b9b66e4b84185c99bc0d1a927', + './include/SearchForm/SearchForm2.php' => 'abde2c406294aa4837c9695bef5e521e', './include/Dashlets/DashletRssFeedTitle.php' => '10771bdc817e8ae49e4a9938d2bcf9d8', './include/Dashlets/DashletGenericAutoRefreshDynamic.tpl' => '355b7490fa2339a87e1fbc7e479dfb73', './include/Dashlets/DashletCacheBuilder.php' => 'a0c56547321767e6b599f98293d2fa39', @@ -2603,10 +2619,10 @@ $md5_string = array ( './include/Pear/XML_HTMLSax3/HTMLSax3/Decorators.php' => '34a9a95566c891f013584073fbadaf7e', './include/Pear/XML_HTMLSax3/LICENSE' => 'a45bb1bbeed9e26b26c5763df1d3913d', './include/Pear/XML_HTMLSax3/HTMLSax3.php' => '11107d97b19feb13feb394cd858603f0', - './include/ListView/ListViewSmarty.php' => '533ed60d9946ad26872a0004e9519b9f', + './include/ListView/ListViewSmarty.php' => 'a69eeef5b31ce1e1fa029519006f9f35', './include/ListView/ListViewData.php' => 'b9721e6b1f1288904b956923b8fb287c', - './include/ListView/ListViewGeneric.tpl' => '6f867b08c99260c7b7ec669c2c85249a', - './include/ListView/ListView.php' => '8cf251743fedb9c81a8310cac2056366', + './include/ListView/ListViewGeneric.tpl' => '32370f4af0164b0985b20c7b7079800c', + './include/ListView/ListView.php' => '3ac177d210dbfa86f9408de539306385', './include/ListView/ListViewFacade.php' => 'e82b5372d43acd05f1dbe5855c40cdbd', './include/ListView/ListViewDCMenu.tpl' => 'e7f7ad82a50d2998a933c7e8c333c080', './include/ListView/ListViewXTPL.php' => '5fff1f22e74a373c216a5358e9be1aae', @@ -2623,7 +2639,7 @@ $md5_string = array ( './include/resource/Observers/ResourceObserver.php' => 'd93dc69d2372859fe8fb0f1068587d54', './include/resource/Observers/SoapResourceObserver.php' => 'bff762397d04d958883d06ed160d8bd1', './include/language/jsLanguage.php' => '3aade005a1d8758085838ed1a22ebf34', - './include/language/en_us.lang.php' => 'f4cddbdc89b3e204c241ddb32e5f14ef', + './include/language/en_us.lang.php' => 'be145284eadc6d4229415b10cefc5f71', './include/language/en_us.notify_template.html' => 'd443be0488e3ce72c2e10984e891d275', './include/pclzip/readme.txt' => '2265cad9ccb84cfcd4093ce26b22dc97', './include/pclzip/gnu-lgpl.txt' => '7fbc338309ac38fefcd64b04bb903e34', @@ -2634,7 +2650,7 @@ $md5_string = array ( './include/SugarEmailAddress/templates/forDetailView.tpl' => '8a913b1d6cbaf35ff7237c8c6022af9c', './include/SugarEmailAddress/templates/forWideFormBodyView.tpl' => '0dc9422da0b8ec60a58ae06d7215c3fb', './include/SugarEmailAddress/templates/forEditView.tpl' => 'ffd92cf011d18742e184a3694db33b20', - './include/SugarPHPMailer.php' => '0d33a8a2f01cf223f24d08c9086d9609', + './include/SugarPHPMailer.php' => '0e474f25604204cadc6cffe46514a19c', './include/tabConfig.php' => '57a8b3ddc91bf135e31f63391409edd6', './include/Smarty/debug.tpl' => '048f29488fb3da08b3fcc5a746489696', './include/Smarty/internals/core.write_compiled_include.php' => '93584e495a0bfb25f946f20f459889fb', @@ -2752,8 +2768,8 @@ $md5_string = array ( './include/Smarty/README' => '1a3fe37eed420a020489d1082ea150c8', './include/Smarty/Smarty_Compiler.class.php' => 'b9a859a96c0d005cee69253bac461599', './include/DetailView/footer.tpl' => '82f240a39faba85858e561048e23fffd', - './include/DetailView/header.tpl' => '9c88585d5c0e14d03fc50ea61168707a', - './include/DetailView/DetailView.tpl' => '414de30cae4905275ff4b2147a104b07', + './include/DetailView/header.tpl' => 'a9e6450bc57678a18a88e2a57b6530d2', + './include/DetailView/DetailView.tpl' => 'a3c4dd95d931815f9845a09fe2e3da33', './include/DetailView/DetailView.php' => '3df8ccba8aca6dffb5969c47001d7435', './include/DetailView/DetailView2.php' => '4f800afa17ab95068341a3474e78fb76', './include/generic/DeleteRelationship.php' => '73e87c09bc4e90c35a551a6d290965c1', @@ -2812,13 +2828,13 @@ $md5_string = array ( './include/generic/SugarWidgets/SugarWidgetSubPanelTopButton.php' => '934a6ff7977d2b3501d1551e31445b3b', './include/generic/SugarWidgets/SugarWidgetSubPanelEditButton.php' => '396cf26585199d9f4709af3e21de089c', './include/generic/SugarWidgets/SugarWidgetSubPanelTopCreateCampaignLogEntryButton.php' => 'eda0760a68c648b6924ff97e44d294e5', - './include/generic/SugarWidgets/SugarWidgetReportField.php' => '363e7e9cd65f94a2877e05bfcb3fc99d', + './include/generic/SugarWidgets/SugarWidgetReportField.php' => '14b211abee99ce2b82279c3145b43aff', './include/generic/SugarWidgets/SugarWidgetSubPanelCloseButton.php' => '8add175bc8b9b0576efc420c9211d7b1', './include/generic/SugarWidgets/SugarWidgetSubPanelTopCreateNoteButton.php' => '3d0a6b29a27135a455a781a0a81e24f8', './include/generic/SugarWidgets/SugarWidgetFieldnum.php' => '15c06a35b7f2ee9f0a41716d5b6d393d', './include/generic/SugarWidgets/SugarWidgetFieldrelate.php' => '671e5fda243f814fb2d3afe9d7a0c1da', './include/generic/SugarWidgets/SugarWidgetSubPanelTopSelectAccountButton.php' => '7c46e299d2783d00cb36be8517100452', - './include/generic/SugarWidgets/SugarWidgetFielddatetime.php' => 'c60ab0c6bb2e9b0cbf2c04ff3488fe89', + './include/generic/SugarWidgets/SugarWidgetFielddatetime.php' => '18c0640e149e709ecc37482c248bb46e', './include/generic/SugarWidgets/SugarWidgetSubPanelEmailLink.php' => '7b67281f140b86aad81ec6e817453467', './include/generic/SugarWidgets/SugarWidgetSubPanelRemoveButtonMeetings.php' => 'b122f559be91ce0a6ea228dc4c94b4c7', './include/generic/SugarWidgets/SugarWidgetFieldfloat.php' => 'c666c7874c49637db91c03b53abaa572', @@ -2845,7 +2861,7 @@ $md5_string = array ( './include/dir_inc.php' => 'faef07151e61f4fce6525afc96bdab28', './include/parsecsv.lib.php' => '839c4fe91eca9008cc3ac181e9ce0258', './include/MySugar/DashletsDialog/DashletsDialog.php' => 'd5014d2e2be6ee2f04ea0e6ce6b160be', - './include/MySugar/tpls/MySugar.tpl' => 'afd7166327f7fdc524cf426aad401516', + './include/MySugar/tpls/MySugar.tpl' => 'ddf46a31c36bb4606dc9d2cdb6de2eef', './include/MySugar/tpls/retrieveReportCharts.tpl' => '9e577c716292d0c9edf2de78ae1c4240', './include/MySugar/tpls/dashletsSearchResults.tpl' => 'b1b794e2ea1f509f62f829db5079f1a3', './include/MySugar/tpls/addDashletsDialog.tpl' => '555233abb02648590a9b44619a27b2d4', @@ -2865,8 +2881,8 @@ $md5_string = array ( './vcal_server.php' => 'd3299c6c47e3a66bea11026bcfbf0ecf', './dictionary.php' => '19245b9374ee0cfc7048c87c7548652e', './HandleAjaxCall.php' => 'e8f0cb63050a3f85e26d5f295c54d8b6', - './ModuleInstall/extensions.php' => '10a1d5b070ae6cfd47071a4a785ba231', - './ModuleInstall/ModuleScanner.php' => 'f9cffaf03d000e24d37e2c77b695d35e', + './ModuleInstall/extensions.php' => 'd17953438bdd75848cce5a5dbe929e5e', + './ModuleInstall/ModuleScanner.php' => '822b419917fa94e60d8a6f60bd1ff16d', './ModuleInstall/ModuleInstaller.php' => '8b09838949b4e3c9bae139b607c81cdd', './ModuleInstall/PackageManager/tpls/PackageForm.tpl' => 'b0f7f452c6c32251c1e88f3f06422018', './ModuleInstall/PackageManager/tpls/PackageManagerScripts.tpl' => '305b5d5a2ea5f04c533b982a5f1422ee', @@ -3283,30 +3299,30 @@ $md5_string = array ( './Zend/Loader.php' => '3a440481f38852f58a39b712ca87d1f9', './Zend/Registry.php' => '56b05bc37aa19203e114fe93782b33b0', './Zend/Crypt.php' => '0e72fd104506094fd2c7682b0b924542', - './json_server.php' => '04bdab8fb6160b89d42c2138429815f6', + './json_server.php' => 'b629a8707237bcaad05acd58c7c6161f', './SugarSecurity.php' => 'e87f1efee51af1d8801dc2376068cee3', './export.php' => '7639b2373c4d0c73765033d70abfb55d', - './data/BeanFactory.php' => 'b48ced42ffd6cc74d6bc14f334511919', - './data/SugarBean.php' => 'beb5df6b33dd3bb220b70f4bb562b6ec', + './data/BeanFactory.php' => '5148eb779611ca40e342900456fc6f29', + './data/SugarBean.php' => '1b38c08d405ddd5414e7015602fbbe14', './data/Link.php' => 'de95f31cf30c2f46a234c4a840c01f84', './data/Relationships/One2OneRelationship.php' => 'f72bfcb39e5c6c6092c41e148f464abf', './data/Relationships/EmailAddressRelationship.php' => '469a91798fa6a92e91766867b145a628', './data/Relationships/M2MRelationship.php' => '048619c6fdf80ac7033447c911bb157b', './data/Relationships/RelationshipFactory.php' => 'd1b759cda7b9dc92f1032ed1be661816', - './data/Relationships/One2MBeanRelationship.php' => '26dea6117861b0d47c0c7f1f6b6f28c1', + './data/Relationships/One2MBeanRelationship.php' => 'aaab2fb06f8b888fb7bf12825f6ff411', './data/Relationships/One2OneBeanRelationship.php' => 'ec639e887d2ff4bb0d16725b2a33b9ac', './data/Relationships/SugarRelationship.php' => '7ecdecd5a7623b1f5a251286ffa48893', - './data/Relationships/One2MRelationship.php' => '9b90a0634f9c68460f6524069d0f60eb', - './data/Link2.php' => '9a423dd110cacdb3b6b9662b62403e2c', + './data/Relationships/One2MRelationship.php' => 'ec99c10eadc77da58700a0418995d78a', + './data/Link2.php' => '08607d058075f66208b31b82037563b3', './data/Tracker.php' => '78c6ca1fadfe9e7984b001fed296f332', './service/core/SugarRestUtils.php' => '183a0d813c88928451133af63934b686', - './service/core/webservice.php' => '7f6d3c42e37ee818424a35bb86f996a4', + './service/core/webservice.php' => 'e27d4bc434ba5536dce4022124104126', './service/core/SugarRestService.php' => '7c80dca082e3f857c98e4114cbbe0438', './service/core/SugarSoapService.php' => 'f4f422721d9e907b35251978d1607093', './service/core/SugarRestServiceImpl.php' => 'd1a216a0907104a536ac894155f42136', './service/core/WSDL.tpl' => 'd41d8cd98f00b204e9800998ecf8427e', - './service/core/SugarWebServiceImpl.php' => 'bdc0e19d2da95de1637ce71b75b987c8', - './service/core/SoapHelperWebService.php' => 'a132b424e253b1fe8c049545cc772465', + './service/core/SugarWebServiceImpl.php' => '6b91e89c7addb670d6d4d92d73c9cba9', + './service/core/SoapHelperWebService.php' => 'ed7f64798d7220d6e97d984c256c211e', './service/core/SugarWebService.php' => '57d68047756a2241b46ddc7bbc7db539', './service/core/PHP5Soap.php' => 'bec53408906a366dd024abff4ef6d5f2', './service/core/REST/SugarRest.php' => 'fe298c96bf12d4a37b4d1bc76609fb1b', @@ -3326,8 +3342,8 @@ $md5_string = array ( './service/v3/registry.php' => '05ac619953459b229719023a5de2f2eb', './service/v3/rest.php' => 'a0958deeacb950bb921ef16afdfd4393', './service/v3/SugarWebServiceImplv3.php' => 'b7aae7d01c1b89c1d769eff3f0799d94', - './service/v3/SugarWebServiceUtilv3.php' => '14a099e12972fffb3e44ebed291eb05b', - './service/v3_1/SugarWebServiceImplv3_1.php' => '089d90f7c588afbcfd47582769d13d00', + './service/v3/SugarWebServiceUtilv3.php' => '7273ac117cbb6211b9e3b06823b3387c', + './service/v3_1/SugarWebServiceImplv3_1.php' => 'cc513f778f8de6847ba7d37976caeebe', './service/v3_1/soap.php' => 'cca72b94407d160e626dd7fedde64e30', './service/v3_1/registry.php' => '1d87b03fc44c8f52798e51794b9d0bab', './service/v3_1/SugarWebServiceUtilv3_1.php' => '978ee442125726b824c909c90e5fa665', @@ -3336,7 +3352,7 @@ $md5_string = array ( './service/v4_1/registry.php' => 'd26ac7142d9c2b8491754f2d01711088', './service/v4_1/rest.php' => '0a622cbfedd7592f7b4cc174bd8245c8', './service/v4_1/SugarWebServiceImplv4_1.php' => '101bd3a92f4502c63d3d9dc8ac923f84', - './service/v4_1/SugarWebServiceUtilv4_1.php' => 'cc2739a8a0852ea26a56a7eb8b84ba77', + './service/v4_1/SugarWebServiceUtilv4_1.php' => 'c80aadfc88dcd6b7e7d7ff1f657b30e6', './service/v2/SugarSoapService2.php' => 'cca6448a6bf0d5c4c3e6db3e744014ce', './service/v2/soap.php' => 'aafda23af747261c47609cbbd1d3fbeb', './service/v2/registry.php' => 'e501bbea7676be78949b574a4084563a', @@ -3345,7 +3361,7 @@ $md5_string = array ( './service/v4/registry.php' => 'eb5f47fb4e4a536aad58984a433b41d5', './service/v4/rest.php' => '0721bd365d3151c72db6f95ce4b7e186', './service/v4/SugarWebServiceImplv4.php' => 'ed700353ab607dd4ef970892b4b70971', - './service/v4/SugarWebServiceUtilv4.php' => 'd7751060998c6e708a794e339a2152e9', + './service/v4/SugarWebServiceUtilv4.php' => 'e0c1a0e4d61fd6c97cf68f4c90cd6d8b', './custom/index.html' => '601a18f179c2ac55779c9bac46942525', './modules/EmailTemplates/EmailTemplate.js' => 'c8ab748acfbda3ad0c5d8f6aa17f267b', './modules/EmailTemplates/EmailTemplate.php' => 'f649e9e4e3b1775ed5a68dbb16219b11', @@ -3546,7 +3562,7 @@ $md5_string = array ( './modules/DynamicFields/templates/Fields/Forms/datetimecombo.php' => '849873ac24bdbc9b7ad9d8f37ad843e4', './modules/DynamicFields/templates/Fields/Forms/date.tpl' => 'ec00987738c128b59b24f349ce98f21d', './modules/DynamicFields/templates/Fields/Forms/image.tpl' => '1b76270f4fa4b2ade44d60df58fe3332', - './modules/DynamicFields/templates/Fields/Forms/coreBottom.tpl' => 'ea7a0bee616edce06ff7e4ad52027d24', + './modules/DynamicFields/templates/Fields/Forms/coreBottom.tpl' => '525a1744859c27a910cdc357de722831', './modules/DynamicFields/templates/Fields/Forms/image.php' => '99d587f125a04c8a23526e4ce0be9b39', './modules/DynamicFields/templates/Fields/Forms/address.tpl' => '65f3d12be2452359875858ffb1521d6a', './modules/DynamicFields/templates/Fields/Forms/phone.php' => '08b9bad6e810ac2bb34c1478a7845ec6', @@ -3702,7 +3718,7 @@ $md5_string = array ( './modules/Emails/MassDelete.php' => 'de2897f4e36f3c288b7afb9035a33abc', './modules/Emails/SearchFormMyInbox.html' => '8487a40c120546ed57546d86fbdc8aba', './modules/Emails/PopupDocuments.php' => 'b99f58a5b000491bad4783f45b744ed2', - './modules/Emails/EmailUI.php' => 'bf9d7d8e7db8e0cb6ed638eb5c42ca8c', + './modules/Emails/EmailUI.php' => '5631e6d90775fa51f01411565c2d1dde', './modules/Emails/Status.php' => '8fac7135044f4315e917a5eb2d4d8ce3', './modules/Emails/Save.php' => '3c0ea8c00c5422e321632a64beb6af93', './modules/Emails/ListViewHome.html' => 'fbb035479e1194d9ac96039ade4b80f5', @@ -3822,7 +3838,7 @@ $md5_string = array ( './modules/Configurator/tpls/SugarpdfSettingsFields.tpl' => '220de2fecf8bd16f2a6bde807a3d1196', './modules/Configurator/tpls/addFontResult.tpl' => '883aab2f2c47f7dd78d69d8094257a79', './modules/Configurator/Menu.php' => '5cbc243dd9e97433e65b6c2c97a5249b', - './modules/Configurator/Configurator.php' => '937f8bf118148f0a849a6af3929bfba3', + './modules/Configurator/Configurator.php' => '22552174f794a9099e8df3232ac5a0ba', './modules/Configurator/views/view.sugarpdfsettings.php' => 'c103556cc9abd3acaa666fb9787e1aee', './modules/Configurator/views/view.addfontresult.php' => '2e92eedd9ae52db5903bb11d5286b77b', './modules/Configurator/views/view.addfontview.php' => '4219a23aa0e9d936b847dc353aa1bd2b', @@ -3830,14 +3846,14 @@ $md5_string = array ( './modules/Configurator/views/view.adminwizard.php' => '9480e2203342deabc404d9768bee258f', './modules/Configurator/views/view.fontmanager.php' => 'ce7094f56148716bbf592e6ee39c5c79', './modules/Configurator/controller.php' => 'b0a13efcd7259e5228b0e4e5153aa69c', - './modules/Configurator/UploadFileCheck.php' => '334b4fecc6d48d8e25d9d352546846fc', + './modules/Configurator/UploadFileCheck.php' => '29d3d018e9753c078562f9c945a4cf4a', './modules/Configurator/LogView.php' => '765205bf61f4ccf357703f41fec2c61b', './modules/Configurator/metadata/SugarpdfSettingsdefs.php' => '11e35d8657b2f5fa72588ec9fab24f54', './modules/Configurator/action_view_map.php' => '335f3982fdb42f04ed981f930a82c733', './modules/Configurator/language/en_us.lang.php' => '8ced23a587b14a9e951f5c8797584dc9', './modules/Configurator/Forms.php' => 'ce7ede2f412813db12e761d60c2eeff1', './modules/Schedulers/Schedulers.js' => 'ce310f70ad5579397f7af6609a4d6601', - './modules/Schedulers/_AddJobsHere.php' => 'ecc086b6d6534b64759e7ac83ea01bc2', + './modules/Schedulers/_AddJobsHere.php' => '2b34d37bb8897cdd0d1100e9f90e6dba', './modules/Schedulers/Save.php' => 'c226203aa66f5352e9f8369558ccfba0', './modules/Schedulers/Menu.php' => 'ec8fe31293309109bc89184d9e59d4d1', './modules/Schedulers/vardefs.php' => '8e502b914fdbb030d4bac26392a2bd85', @@ -3903,14 +3919,14 @@ $md5_string = array ( './modules/InboundEmail/DetailView.php' => 'a171268c4c9e85ac2fc62efce30deeb7', './modules/InboundEmail/Delete.php' => 'b49ee65d8850ff8ff370ebf237b0acb5', './modules/InboundEmail/Popup.php' => '472052c2da7990c6e8d63a0a2dccbbd2', - './modules/InboundEmail/InboundEmail.php' => '4ed6b6cb6b0602abf3a6f2907774d78b', + './modules/InboundEmail/InboundEmail.php' => '06b4db5d0b2a6f0febff7b538897f237', './modules/InboundEmail/ListView.html' => 'd76aa28386e3f7165f62dabfc6f0beb7', './modules/InboundEmail/index.php' => '6b54e0739c45bd059cc2da5f3aa41d9a', './modules/InboundEmail/language/en_us.lang.php' => 'ae833e99a3be579da67788c144af7ee2', './modules/InboundEmail/InboundEmailTest.php' => '04ac2888e0372a0315d4086ec2e765f5', './modules/InboundEmail/SaveGroupFolder.php' => '59a7d467ab0166f09f5b0e746898fecb', './modules/InboundEmail/EditView.html' => 'b6bd18a951e87e1867709dd48b1be198', - './modules/ModuleBuilder/tpls/layoutView.tpl' => '0b63f12c6cd37e2dffbe4b04117f5a68', + './modules/ModuleBuilder/tpls/layoutView.tpl' => 'cb1e0bd7dddfe9f9280cef0cd7841c4c', './modules/ModuleBuilder/tpls/tabBG.png' => '8e2561b0bba66f327d602e6c5f06aa08', './modules/ModuleBuilder/tpls/LayoutEditor.css' => 'd05c482d3367fb032f5314210df2ffee', './modules/ModuleBuilder/tpls/includes.tpl' => '10927a4f55674bb2ab628a67dfa6c696', @@ -3963,7 +3979,7 @@ $md5_string = array ( './modules/ModuleBuilder/parsers/relationships/OneToManyRelationship.php' => '76761d4122cd790065a59f92bd64bc96', './modules/ModuleBuilder/parsers/views/UndeployedMetaDataImplementation.php' => 'd08c83158fc599313de72722cc8d9ea9', './modules/ModuleBuilder/parsers/views/UndeployedSubpanelImplementation.php' => '9bf70fa555014fd415478b66ee2de930', - './modules/ModuleBuilder/parsers/views/GridLayoutMetaDataParser.php' => '9ba5877abde15af9017cb5357d2bb490', + './modules/ModuleBuilder/parsers/views/GridLayoutMetaDataParser.php' => 'bdc0b4a67e68bb9832792ea411c9b851', './modules/ModuleBuilder/parsers/views/PopupMetaDataParser.php' => '983372e3529c23ff91237434f7c3e9bb', './modules/ModuleBuilder/parsers/views/MetaDataImplementationInterface.php' => '96a4fcfa2ee73ff09cb2d868c3ac686f', './modules/ModuleBuilder/parsers/views/DashletMetaDataParser.php' => '5135692589012551cd63d5efd43419e1', @@ -3982,19 +3998,19 @@ $md5_string = array ( './modules/ModuleBuilder/parsers/parser.dropdown.php' => 'e0d2906621908ce85d1bf2ca907e4cec', './modules/ModuleBuilder/parsers/constants.php' => '859d39d8e265b729077ef95e6f3dfb6e', './modules/ModuleBuilder/parsers/parser.modifysubpanel.php' => 'c3848b1a209455fe7f4a3a1fcbb53fe4', - './modules/ModuleBuilder/parsers/ParserFactory.php' => 'ab9f0e24322d43c62a5e55411670cbd9', + './modules/ModuleBuilder/parsers/ParserFactory.php' => '5500ccbe71683ad3f5500c060e95e22e', './modules/ModuleBuilder/parsers/StandardField.php' => '1c8dd4d86e92c298088b945884d971eb', './modules/ModuleBuilder/Module/StudioModuleFactory.php' => '5a0a2bd755bc8add80477aa029324416', './modules/ModuleBuilder/Module/MainTree.php' => '2817547b3c188df1d5c4b0bed2510552', './modules/ModuleBuilder/Module/StudioTree.php' => 'ba8cb5bb1828ab02c95b763ebb0d508f', './modules/ModuleBuilder/Module/StudioBrowser.php' => '92c13d7c173dd243c2a72c821c17189f', - './modules/ModuleBuilder/Module/StudioModule.php' => '5b74fa0e37cab0c3268e1bf46545bf09', + './modules/ModuleBuilder/Module/StudioModule.php' => '0e155825ee6a96f535e3c6af592dd63d', './modules/ModuleBuilder/Module/DropDownTree.php' => '1efd3171700422c9bb838a0e8a8c8699', './modules/ModuleBuilder/Module/DropDownBrowser.php' => '70c0cff3e4a7abee8a2a4bac01539837', './modules/ModuleBuilder/views/view.modulefield.php' => '0ddd7c1412185c73d3aa2428d7ca8ecb', './modules/ModuleBuilder/views/view.relationship.php' => '59e94a5659c958248c3b6353e19ad4d0', './modules/ModuleBuilder/views/view.history.php' => '300fe8425bd9b4758ed01d7796c295c1', - './modules/ModuleBuilder/views/view.layoutview.php' => '9739a1a3ce7795392008e15884e9e23a', + './modules/ModuleBuilder/views/view.layoutview.php' => 'ee1bbc8abb49557a6a3a9d98cb808658', './modules/ModuleBuilder/views/view.displaydeploy.php' => 'a028806a1ece6afc4c08f75d5ba1ec9c', './modules/ModuleBuilder/views/view.displaydeployresult.php' => 'ad8f2e54fe51b48031a01418519945f8', './modules/ModuleBuilder/views/view.relationships.php' => '7358fdc5124faa2761a6d5dcdc6ba6b0', @@ -4026,7 +4042,7 @@ $md5_string = array ( './modules/ModuleBuilder/javascript/JSTransaction.js' => '6022b3b17d3bace0ecd4e31b747f36fb', './modules/ModuleBuilder/javascript/studiotabgroups.js' => '9122fbe637449b8419dcf54138796d61', './modules/ModuleBuilder/javascript/studio2ListDD.js' => '89470dcfe5c0f6db12a16eeefe3ed261', - './modules/ModuleBuilder/javascript/studio2.js' => 'fd387f59c9ffe44be63fca80334739f6', + './modules/ModuleBuilder/javascript/studio2.js' => '83680fc8bd2c75e5df56f60dc4489d1c', './modules/ModuleBuilder/javascript/SimpleList.js' => '5fb0b6e7e22287db56a3b5cd4c56f183', './modules/ModuleBuilder/javascript/wizardTemplate.js' => '3d3ab9ff2f4bbf520c3d708c370919d9', './modules/ModuleBuilder/javascript/studio2PanelDD.js' => '5f88544d725e6f2f11fff83f65307043', @@ -4040,7 +4056,7 @@ $md5_string = array ( './modules/ModuleBuilder/MB/MBLanguage.php' => '1d1a81b9394953038980af83a724792b', './modules/ModuleBuilder/MB/ModuleBuilder.php' => 'ab6b03dfeb337023aba6a3f2ace024ef', './modules/ModuleBuilder/MB/MBRelationship.php' => '387ceae2d9fbaeb0b6c5a04f59e869d5', - './modules/ModuleBuilder/language/en_us.lang.php' => '564265ea2ff0802a1ac262b6b4b2d89a', + './modules/ModuleBuilder/language/en_us.lang.php' => '86c7fb502b7430ebe576e33893527ddb', './modules/ModuleBuilder/Forms.php' => 'e0b1a511f6979cc7536df6a72dcf466d', './modules/BeanDictionary.php' => '233575feabf6c1890205aaeef299c689', './modules/ACL/Save.php' => '866f5017539a906c1df5010bc42e3829', @@ -4208,7 +4224,7 @@ $md5_string = array ( './modules/EmailMarketing/Forms.php' => '76760b77bb2cf3497833ae2d9f479b78', './modules/EmailMarketing/SubPanelView.html' => 'd31288bfe75e2766f3094dace2f1c93e', './modules/EmailMarketing/EmailMarketing.php' => '36d0a297001f84540de585629d3537d2', - './modules/EmailMarketing/EditView.html' => '39626ae31c210903aa68e029018738ce', + './modules/EmailMarketing/EditView.html' => '7c7eeac3d3c8f1d47f7dccea4eec3ad4', './modules/Relationships/vardefs.php' => '14559d848f0a4a5918e8c83910137d90', './modules/Relationships/views/view.editfields.php' => '447aa2b3ae9dc7f97dfe01fac38a75e1', './modules/Relationships/RelationshipHandler.php' => 'b910c7b8f19ec2a168642d3c2a68c7fd', @@ -4254,17 +4270,17 @@ $md5_string = array ( './modules/Users/UserEditView.js' => '829b9bd128f07eeb48181aaee9ca6576', './modules/Users/UserViewHelper.php' => '7e56be60efbe5ac4facf17adfa95707d', './modules/Users/Error.php' => 'e47d743efb522af6e4861396be53e8b6', - './modules/Users/Save.php' => '4cd35037cbf01fae5b655fab371a4272', + './modules/Users/Save.php' => '51cbd4dede5b4547eb3075830664dbd5', './modules/Users/tpls/DetailViewFooter.tpl' => '41360606a7be7665511d0a4edfb4924b', - './modules/Users/tpls/EditViewFooter.tpl' => '381d83f79812fd28585583730fd7fd1f', - './modules/Users/tpls/EditViewHeader.tpl' => 'a3db8cb89fe92f5d15ad18aee0587848', + './modules/Users/tpls/EditViewFooter.tpl' => 'd9e9670a7b2eaa592ea7f72897bf80b7', + './modules/Users/tpls/EditViewHeader.tpl' => '970b6de2f23eeac8d273ff4e1694a589', './modules/Users/tpls/wizard.tpl' => 'f8f87728585eb6f754f0d5ec52d640ff', './modules/Users/tpls/QuickEditFooter.tpl' => 'ca1415ac61ae726339e359a43a25d97e', './modules/Users/tpls/DetailViewHeader.tpl' => '19474abc8c3237969d39112b812770ca', './modules/Users/tpls/EditViewGroup.tpl' => '216c9826dbe366a4658d1f45201a8ad4', './modules/Users/ChangePassword.php' => '2a6c396c3bb376eb1e0665d60f85ab5d', './modules/Users/Menu.php' => 'd57ecd83a83934875b98d855f9175a37', - './modules/Users/vardefs.php' => '071168ad264ffb70d4180b3c6fee11f2', + './modules/Users/vardefs.php' => '9a67cfe3b21b9c56a6883ca3a0434e32', './modules/Users/PopupUsers.php' => '4014d4aec3ea2b4197dcddf8f0cb726d', './modules/Users/ListRoles.php' => '5aecfc211a0f4f9d08010a3f7ab4f334', './modules/Users/authentication/SugarAuthenticate/SugarAuthenticateUser.php' => 'd560e09d6f9611d7e27b33567adb2e51', @@ -4296,7 +4312,7 @@ $md5_string = array ( './modules/Users/controller.php' => 'ab707e79b219d0f9a9302b7549cf9d8e', './modules/Users/SaveSignature.php' => 'cc2276e326ce4a58a4fce9b147302c4f', './modules/Users/User.php' => 'bff839e28f1a81ccbb04d2e86c2efc20', - './modules/Users/login.tpl' => '7655c5b489de7a779cd7191d2ede3fa2', + './modules/Users/login.tpl' => 'ea831fdb2eaeac643665acb6cb947f33', './modules/Users/LoggedOut.tpl' => '56f709612a02e111d2411a771b11cd80', './modules/Users/SaveTimezone.php' => '3a27e5b03cbb1a9501401521dd2c1168', './modules/Users/Login.php' => 'ff1d42fe242df34fcb1233e429c786e9', @@ -4304,6 +4320,7 @@ $md5_string = array ( './modules/Users/field_arrays.php' => 'dd10e757de20644a16a95c2e87bcecac', './modules/Users/UserSignatureEditView.html' => '583e97e48d516a55745369222600b215', './modules/Users/SetTimezone.php' => 'c44b79aaff575d0ca6250a1f1b7dcd84', + './modules/Users/UpdateTourStatus.php' => 'c17efc8a69b4d8f2ef06f5add7d86841', './modules/Users/password_utils.php' => '81d971c14523bc6a3e494c5c0bf1933f', './modules/Users/SetTimezone.tpl' => '63de1550c8415a4a7f510846b0f1010a', './modules/Users/GeneratePassword.php' => '48bf5ad222ec34fb4df62baf30e134be', @@ -4329,7 +4346,7 @@ $md5_string = array ( './modules/Users/metadata/detailviewdefs.php' => '0d35380da7742becc69d9a8e287eede5', './modules/Users/UserSignature.php' => '410eac350e431f5f5e88ca59a01ad7d3', './modules/Users/Popup_picker.html' => '44ecf49fcfd43110437ff32d25736fa1', - './modules/Users/Changenewpassword.php' => 'd957ddd60abddcc028f74079bc7e05ac', + './modules/Users/Changenewpassword.php' => 'a4c0bfaaf278973c844be58320b81e53', './modules/Users/language/en_us.lang.php' => '4bb673fcd8bc1a00b98bbe7cd2a476a2', './modules/Users/Logout.php' => '4d8773fffd6b85b1f39a61e05faf472f', './modules/Users/Popup_Users_picker.html' => '72ca55f89e936ccf6c8b1f252ee54236', @@ -4418,7 +4435,7 @@ $md5_string = array ( './modules/UpgradeWizard/uw_ajax.php' => '8ed909021c2e338d0a185d01fa046a80', './modules/UpgradeWizard/commitJson.php' => 'e02a21bb4ce00448e6bbb98526f860dd', './modules/UpgradeWizard/UpgradeRemoval.php' => 'dafb5c6a72582cf510bca521d1c1bcb6', - './modules/UpgradeWizard/silentUpgrade_step2.php' => '6d3658286db46d41857580f272eda89d', + './modules/UpgradeWizard/silentUpgrade_step2.php' => 'a8394b5b6de525b860fcc88b786ca115', './modules/UpgradeWizard/UploadFileCheck.php' => 'e5d0bac07ff5bb02ffaf9db0b605c9f4', './modules/UpgradeWizard/silentUpgrade_dce_step2.php' => '6ff56d8935422615d4a5d3cb078b6e40', './modules/UpgradeWizard/layouts.php' => '8e4ae4f83d7825ddb7dca7ef2dfc62b3', @@ -4426,7 +4443,7 @@ $md5_string = array ( './modules/UpgradeWizard/commit.php' => '95151a7c632a6f3b8afea1afdd9ec077', './modules/UpgradeWizard/processing.gif' => 'd7c43fc19181ee59862601bfce100b41', './modules/UpgradeWizard/systemCheckJson.php' => '1b3ca3638039d16eab4dc010373effcd', - './modules/UpgradeWizard/end.php' => 'ed7cf85069a322ef09632607f5829861', + './modules/UpgradeWizard/end.php' => '156a8eec0106685ba60de86190381f0b', './modules/UpgradeWizard/uw_utils.php' => '9837434d4d6640181bbc0908b18d8abc', './modules/UpgradeWizard/preflightJson.php' => 'f9430751b95094f6d831f98fbaed9d80', './modules/UpgradeWizard/upgradeTimeCounter.php' => '13650e724da4e4fe127bae4a8073565c', @@ -4459,7 +4476,7 @@ $md5_string = array ( './modules/UserPreferences/field_arrays.php' => 'f2e3b2179e594e95d7e5d3fb2786323c', './modules/UserPreferences/index.php' => '903eebcc2f8a7d04d245821c5f13121f', './modules/UserPreferences/UserPreference.php' => '17db32c275129ffaf0253f1e72d79ab7', - './modules/Calls/CallHelper.php' => '0a3e16eb98321a42cd2b078b094f1ad8', + './modules/Calls/CallHelper.php' => 'b351db4a49e4b47b518a04e4b20c504f', './modules/Calls/Save.php' => '89bcb06dff3026f3627692ee1616d86a', './modules/Calls/tpls/footer.tpl' => '7c4a89f076f85e253dcfa064d1a86ae3', './modules/Calls/tpls/QuickCreate.tpl' => '83609a9e601a5599dc3f3d2674665941', @@ -4470,7 +4487,7 @@ $md5_string = array ( './modules/Calls/CallFormBase.php' => '5d05ab5c814c2b716ca3b7ee015f17a0', './modules/Calls/views/view.list.php' => '5b950a91d105b087fdf4a2972f082e54', './modules/Calls/views/view.edit.php' => '8c94e4b5f35e895b73cf1236abb252fb', - './modules/Calls/Call.php' => 'a30932e15848e4ac7c472f4296f16acb', + './modules/Calls/Call.php' => '730aa76c67ae97883a61557b1c607cae', './modules/Calls/field_arrays.php' => 'd7fcc70cbde9c22dae63e1bbec29154d', './modules/Calls/SubPanelViewInvitees.php' => 'da01bcec9878607ff688f390bfed2cb0', './modules/Calls/metadata/searchdefs.php' => '892464b109427176fc0dc9ca870ae1e4', @@ -4484,7 +4501,7 @@ $md5_string = array ( './modules/Calls/metadata/listviewdefs.php' => 'd8fbb386c9825e95b0d20a90bef4a1fc', './modules/Calls/metadata/additionalDetails.php' => '806492f1654ddb97a247b3d7957b0abf', './modules/Calls/metadata/studio.php' => 'fe87c7c9d8abf393806b94bbb9313d60', - './modules/Calls/metadata/detailviewdefs.php' => '9afe449256618a2a01c8207a2a802ce9', + './modules/Calls/metadata/detailviewdefs.php' => '6136bdc6c445025f4f874ac29ccc065f', './modules/Calls/Dashlets/MyCallsDashlet/MyCallsDashlet.data.php' => 'bbb096633528bb22b112d6e3dc78d9d1', './modules/Calls/Dashlets/MyCallsDashlet/MyCallsDashlet.meta.php' => '81158ed6fa50d810929b4ff429657161', './modules/Calls/Dashlets/MyCallsDashlet/MyCallsDashlet.php' => '6bf0c16b793ffcadcf14333530dafe83', @@ -4638,7 +4655,7 @@ $md5_string = array ( './modules/Campaigns/Menu.php' => '56fe7db6c8c20af19da4a23f76418ecf', './modules/Campaigns/vardefs.php' => 'a0711d1a9689d9611c48420d26ce150f', './modules/Campaigns/RoiDetailView.php' => '10c41669b01bb56f43388c483418bf3f', - './modules/Campaigns/WebToLeadFormSave.php' => 'fece56e609c236954a83ec79ccc8220e', + './modules/Campaigns/WebToLeadFormSave.php' => 'ce3c6af9d2dd9d2147cf7a4450e5783b', './modules/Campaigns/WizardHome.html' => 'b1876f7fc33ebb237541ce6769ba2a14', './modules/Campaigns/Schedule.html' => '5e032b1c1b2ed03848af26e415926685', './modules/Campaigns/DeleteTestCampaigns.php' => '0252ecdf2e0978b07d39c1bb63405864', @@ -4716,7 +4733,7 @@ $md5_string = array ( './modules/Employees/metadata/listviewdefs.php' => '41c458a66e549068c79483258175198b', './modules/Employees/metadata/studio.php' => '69518398640ba7ad59a093a447d2af6c', './modules/Employees/metadata/detailviewdefs.php' => '7c931e608a51c630eedfd23315bd52e5', - './modules/Employees/Employee.php' => 'cc2aeb8ddf7b352db24d2f62e99d3b79', + './modules/Employees/Employee.php' => '31b02a2b604a13bf7c3b8c2cf14cdebc', './modules/Employees/Popup_picker.html' => '2c5a03f7134c836c7dc66048343273d4', './modules/Employees/EmployeesStudioModule.php' => 'c375357117147eb5e1e2845861ed68f7', './modules/Employees/Popup_picker.php' => '8dd56afa5b0762070993b9cecea17adc', @@ -4761,7 +4778,7 @@ $md5_string = array ( './modules/vCals/vardefs.php' => '6da81e3f0d0c44fa2a0110c8be208e17', './modules/vCals/HTTP_WebDAV_Server_vCal.php' => '5a6b18b368756d72906cb30a6a8c5bbe', './modules/vCals/field_arrays.php' => 'edf597f757a7476101f8c0a6f9ae7bd5', - './modules/vCals/vCal.php' => 'bd0231bc97af713a77bcd6caee73727b', + './modules/vCals/vCal.php' => 'fa6be09ed4e177d569a1427d64862f7a', './modules/Bugs/Bug.php' => '3badfdca740aa6547bc04644efa3c470', './modules/Bugs/tpls/QuickCreate.tpl' => '8cb257fc67aa10e35b93927896fcc61f', './modules/Bugs/Menu.php' => '08b918b895b6e4e30507e6329482da6e', @@ -4799,7 +4816,7 @@ $md5_string = array ( './modules/Contacts/tpls/QuickCreate.tpl' => 'c460011bd34d580b5f16c1adfdede9c4', './modules/Contacts/Menu.php' => '3cdb52ed118ba2c8f466607076501330', './modules/Contacts/vardefs.php' => '6c909504d34b50c16807fdd8067f857e', - './modules/Contacts/ContactFormBase.php' => 'f0aadb90140e4f37efc83f654e074502', + './modules/Contacts/ContactFormBase.php' => 'f62b0dc28f294408ef9de78aab3062d0', './modules/Contacts/ShowDuplicates.html' => '71949d6852e24da1346b2f5799e6eb94', './modules/Contacts/views/view.closecontactaddresspopup.php' => 'bb8bdfe65be31ba0dced32cc16a2a0ae', './modules/Contacts/views/view.quickcreate.php' => 'b6287d02b002b75be781e8fde11bfab3', @@ -4936,10 +4953,13 @@ $md5_string = array ( './modules/DocumentRevisions/Forms.php' => 'a9672ec8e20be2699753fccba26094ed', './modules/Project/Project.js' => '35bb21807dc063998feff6be8f3bf816', './modules/Project/Save.php' => '962c137bd5e6dda962d8421be91f8982', + './modules/Project/tpls/QuickEditHeader.tpl' => '0125383ec52c7c5b595b0c5586985834', './modules/Project/tpls/QuickCreate.tpl' => '9829aa1a4f4b1cb2436f318416abf27e', + './modules/Project/tpls/QuickEditFooter.tpl' => '70234b658d839c19eadb7a9a973ecc2b', './modules/Project/Menu.php' => '2e76d746caf007f46f88f1ca809a2761', './modules/Project/vardefs.php' => '5b6fe0a43a2244dd15203397c828c214', './modules/Project/views/view.templatesedit.php' => '11321a6adb98ab1c3d5e8679baa25da7', + './modules/Project/views/view.quickedit.php' => 'b41ca19166cde6195b448805e0d9db73', './modules/Project/views/view.list.php' => 'e63a403ef909743f394fe81f9f892c47', './modules/Project/views/view.edit.php' => '78211e01c8a7036cfeca8f96debed7fe', './modules/Project/views/view.templatesdetail.php' => 'ab9ae2ad02c7c78ad838befe9ad09ddd', @@ -5068,7 +5088,7 @@ $md5_string = array ( './modules/Administration/DiagnosticDownload.php' => '5a09f54e964d71d49211bde5cb49a449', './modules/Administration/DisplayWarnings.php' => '3b14925531f2d1011ecc1ce03478314f', './modules/Administration/RepairJSFile.php' => 'f8cf5338d5659ea27a2662d44150b7fd', - './modules/Administration/metadata/adminpaneldefs.php' => 'f851308d587e01b1d5558326ef0e0e66', + './modules/Administration/metadata/adminpaneldefs.php' => '46ef34966f9ac3a0340edbafe667c1a4', './modules/Administration/metadata/SearchFields.php' => '787123be8e7e907e9754da7bf36ead0a', './modules/Administration/clear_chart_cache.php' => 'a4be1a29a9f98f1f86215c6540c0b712', './modules/Administration/action_view_map.php' => 'e70c869d8157de4584b4da0aec2117e4', @@ -5081,7 +5101,7 @@ $md5_string = array ( './modules/Administration/PasswordManager.php' => '11ef65dbd8f4ef09c813483507fff134', './modules/Administration/Locale.tpl' => 'bb9afeb5e9db4919bdcd1808cabf2999', './modules/Administration/RebuildExpressionPlugins.php' => 'a926f301737fb11ba1a71673eb51424c', - './modules/Administration/language/en_us.lang.php' => '45beb41d63e6c2dad275e3037d1f1f7f', + './modules/Administration/language/en_us.lang.php' => 'b228aa901531c6c26903232abae8993e', './modules/Administration/UpgradeHistory.php' => 'a9ec8a2612a5d3404e974d53de8b4311', './modules/Administration/upgrade_custom_relationships.php' => 'fe1239f73daa16e6a8b7f3170c8cad23', './modules/Administration/ImportCustomFieldStructure.php' => 'fd2baf8134f11375810c5c4daa52c889', @@ -5182,12 +5202,16 @@ $md5_string = array ( './modules/Prospects/Prospect.php' => 'e0d26b2ae630440b3443e5aad290793b', './modules/Prospects/Import.php' => '614497f986383f860516ab61657971cc', './modules/Home/about.js' => '03fa705aef3b3a4b5ab6ac20d2fed0c0', + './modules/Home/tour.js' => '02de392c74cf4fe1ee3d2420b1909853', + './modules/Home/tour.css' => '010dec86c845782e324a5a24d6ed7766', './modules/Home/Home.html' => 'db09f83e17d4b882ef673c2cd01751ec', + './modules/Home/tour.tpl' => '990ef52a6086b790c4ee6f40c312015d', './modules/Home/SubpanelEdits.php' => 'a7c382727fd45ea8e3f3be39846b7ada', './modules/Home/QuickSearch.php' => '858a24650ffb6f432d28c006371293b6', './modules/Home/Home.tpl' => 'a2bd30c3b40d5df6b929a274ddff83ac', './modules/Home/Menu.php' => '9f95dba812226231c76b38da981f6513', './modules/Home/sitemap.tpl' => '3619e568a9ad07ab4b5e35dd3780b298', + './modules/Home/views/view.tour.php' => 'b2404d4d157c9e186c6830d5844e1801', './modules/Home/views/view.additionaldetailsretrieve.php' => 'b0ca3fbad18270986844993c737e49d3', './modules/Home/views/view.list.php' => 'ddcaf125190670eb41676357c6e8f903', './modules/Home/views/view.modulelistmenu.php' => 'a1a8df55d774b049f8728fd70d8de48c', @@ -5197,7 +5221,7 @@ $md5_string = array ( './modules/Home/UnifiedSearch.php' => '5ae8ec639a6e9409bc35303a94921b35', './modules/Home/DynamicAction.php' => '8362cee444b8941ac8d808de2b6141d8', './modules/Home/UnifiedSearchAdvanced.tpl' => 'e0c7d63a16de2718887838c5617ac706', - './modules/Home/action_view_map.php' => '42ac212dbe9fd781aa849d252222a781', + './modules/Home/action_view_map.php' => 'a4266c315f2561350486347856a74b34', './modules/Home/TrainingPortal.tpl' => '1e181d4b3f021a74b7ce165a71558863', './modules/Home/Dashlets/ChartsDashlet/ChartsDashlet.php' => 'b1d170d157bdbd192a1aab8d2141fa56', './modules/Home/Dashlets/ChartsDashlet/ChartsDashletScript.tpl' => '2df14de190bfe8608d647ab00264fd0e', @@ -5233,8 +5257,8 @@ $md5_string = array ( './modules/Home/Dashlets/JotPadDashlet/JotPadDashlet.php' => '30ed52af9d9adf1248e75aeb79f13da2', './modules/Home/Dashlets/JotPadDashlet/JotPadDashletOptions.tpl' => 'a071ef1e73c24bb302f83cb1bc7d7de6', './modules/Home/dashlets.php' => 'd7ee77314c504c10c60f385fe3f97cda', - './modules/Home/index.php' => 'ac7320ff1125be9efff83bdc6f38b3f5', - './modules/Home/language/en_us.lang.php' => '1fbbe8b4add8d2580060c3638220e011', + './modules/Home/index.php' => '7b9a63243baa0e43020546536d54788c', + './modules/Home/language/en_us.lang.php' => '700e6beb201b01c09be395e83b58769a', './modules/Home/SaveSubpanelLayout.php' => '91dfc82a810257041e19df963b342b55', './modules/Home/UnifiedSearchAdvancedForm.tpl' => '6213260d588340fc97e52ec0f3e1b977', './modules/Home/UnifiedSearchAdvanced.php' => 'f4d08a6b065441300e397132cbcd6125', @@ -5244,8 +5268,8 @@ $md5_string = array ( './modules/Home/LastViewed.php' => 'e4fd8c8ebf25ad8a93173deabf4b35bc', './modules/Home/AddToFavorites.php' => '2d1240598be9e7f74c497fe3a6578868', './modules/Home/TrainingPortal.php' => '1ec4a300d6dfd51f80eb642eee05f0f0', - './cache/include/javascript/sugar_grp_jsolait.js' => 'c2b9bc248224b3c1001b19487f3ab99b', - './cache/include/javascript/sugar_grp_quickcomp.js' => '53eeda5a463ab179f2cac0b0221c12d8', + './cache/include/javascript/sugar_grp_jsolait.js' => '9aced6d7d2669515690f61e506834ed9', + './cache/include/javascript/sugar_grp_quickcomp.js' => '464a1159cee19a73c9a4035b47a6e18e', './cache/include/javascript/sugar_grp_emails.js' => '966628c4d758082a9a8250ef64d1c5b1', './cache/include/javascript/sugar_grp_yui2.js' => '53c8d4d026a0adc7ea775e6488245de5', './cache/include/javascript/sugar_grp_yui_widgets.css' => '17f5b268fda1a8a3e27b41ebefe4d408', @@ -5253,7 +5277,7 @@ $md5_string = array ( './cache/include/javascript/sugar_grp1_yui.js' => '9c3853420e26cad638181691de71e991', './cache/include/javascript/sugar_field_grp.js' => '339b3b1d92f554dbac7fad410360c8f1', './cache/include/javascript/sugar_grp1_jquery.js' => '49498e5d14244f125e6bcadbd6e1ea7d', - './cache/include/javascript/sugar_grp1.js' => '86000e841ececb074db1f967a31f559b', + './cache/include/javascript/sugar_grp1.js' => '7a7f9d3e7e0ec6f805b291f9d905db63', './cache/layout/index.html' => '9cd784063d39b18d308932c28c385853', './cache/images/index.html' => '9cd784063d39b18d308932c28c385853', './cache/xml/index.html' => '9cd784063d39b18d308932c28c385853', @@ -5324,7 +5348,7 @@ $md5_string = array ( './metadata/prospect_lists_prospectsMetaData.php' => 'fe3dc7d813428ca0fa774884a88ef5c4', './metadata/inboundEmail_autoreplyMetaData.php' => '7c670a62c7142827bbdf675c8b4be221', './metadata/acl_roles_actionsMetaData.php' => 'a3446107943a271bf6e329a80deb06e8', - './sugar_version.php' => 'b80ef7f8b5db44580e762999677978ff', + './sugar_version.php' => '1d0d9c3f57e59bd9da12fc219472bbb2', './cron.php' => '96a6fd7893809132e902086e77dde30c', './log4php/LoggerManager.php' => 'fa34194306cd50c01b71d8d5060ee362', './TreeData.php' => '7040af43bf01c450f4e225ece5e3f30c', @@ -5924,7 +5948,53 @@ $md5_string = array ( './themes/default/images/plug-in_Excel.gif' => 'ba18135f4a74f4d35f90f786bdbbdb87', './themes/default/images/icon_DetailView.gif' => '7e52a99c33829596b0a3210c5202a12d', './themes/default/images/arrow_down.gif' => '7ae60aa70170713428e265b1cc695291', + './themes/default/less/modals.less' => '79e642a069898452a6163b7649b4869a', + './themes/default/less/grid.less' => '093b04da109c33b5cf412a342587fc7c', + './themes/default/less/mixins.less' => '88e9da92e980d0656c86dc08d8af4adb', + './themes/default/less/alerts.less' => '53ab8f4134194d7275df313710a1212e', + './themes/default/less/sugarmobile.less' => '3b8e9c646188fa3a7a97e51460f1f9e9', + './themes/default/less/bootstrap-mobile.less' => 'e094b3a77f8f38b595b617b5d907747b', + './themes/default/less/sprites.less' => '2c3bedce470102664f6ba7620ec42e99', + './themes/default/less/scaffolding.less' => '68e322445c61f5c75c4a841f307d2b72', + './themes/default/less/type.less' => 'd96279ac0848b821e1f3998d627b34c4', + './themes/default/less/navs.less' => '7f9fc3a73d6299b337186175ca410111', + './themes/default/less/breadcrumbs.less' => '0cfa7b81b1c046851f81b92de6c4f25d', + './themes/default/less/code.less' => 'a7b99ab8266f8950d839f44213e875bd', + './themes/default/less/wells.less' => '07cc7d04d7f7f344742f23886cbe5683', + './themes/default/less/bootstrap.less' => '6d7ea975856359e0e79d85737f6b503e', + './themes/default/less/button-groups.less' => '1b9f8b26b4b2b3f0e9969212622cfaf4', + './themes/default/less/font-awesome.less' => 'fd0453172d43d0fdd57cebc1186401ae', + './themes/default/less/carousel.less' => '3ad7d4b5a908686f352f0cdc085644b3', + './themes/default/less/navbar.less' => '16d39b241ef60ee5292d18386c9d0b37', + './themes/default/less/sugar.less' => '15673889377c652687822a66b54239da', + './themes/default/less/variables.less' => '01f56f5ec66f9f53d557300be32bde89', + './themes/default/less/close.less' => '8fba93ac6138881e3b6ba03d4a134ccd', + './themes/default/less/utilities.less' => 'd1f5479d4b119cb29db8da954a108637', + './themes/default/less/tables.less' => 'b92d7ea092b023ff15f9dd419fc781c4', + './themes/default/less/layouts.less' => '0b33b1b0abd196f531fa34fb1db816e8', + './themes/default/less/popovers.less' => '8bf0b5520c716fff4a467a198f3eab49', + './themes/default/less/buttons.less' => '7251b0a711e019a47f4f81aaf7dc23d5', + './themes/default/less/accordion.less' => '421d748864561de1a01ac7c00b287010', + './themes/default/less/responsive.less' => '09afd23e8b34e2b1e4fd15a54fdb9784', + './themes/default/less/pager.less' => '38cd0dce550569e458073daf0285498d', + './themes/default/less/component-animations.less' => '9ac05b18d1ab05d519b3840074f50948', + './themes/default/less/forms.less' => '327cb0754969b62b111199666ec57895', + './themes/default/less/labels.less' => 'e23f0414a9db38a2f41043e22d21aa91', + './themes/default/less/progress-bars.less' => '217bf11672a442af71638250da08b65d', + './themes/default/less/pagination.less' => 'aa8d1da3d823591f2b86d10e845524e6', + './themes/default/less/dropdowns.less' => 'd93b812e0b94bc3f1a3545efd47cb276', + './themes/default/less/chosen.less' => '5f580726899c2906c0cde5aea88e4086', + './themes/default/less/tooltip.less' => '6d1bfe6ae31c2ce93477915fe0ca34df', + './themes/default/less/reset.less' => '17074dfa79969a511a87f7b202d37c62', + './themes/default/less/thumbnails.less' => 'e75256eb7fd91d25b80ec01c7f9aa585', + './themes/default/less/hero-unit.less' => 'ba236d05e19a22ca5a58c4f3d048ba46', + './themes/default/font/fontawesome-webfont.svgz' => '1fe4ffdfa48998422cbdae57cd3baca6', + './themes/default/font/fontawesome-webfont.woff' => '975395ab4719fc196dc0245c2aaf7344', + './themes/default/font/fontawesome-webfont.eot' => '0c064252fc8fc4749fd83cf4ff8ea53d', + './themes/default/font/fontawesome-webfont.ttf' => 'ed1087510537f07b14eb94d5bf45cdb7', + './themes/default/font/fontawesome-webfont.svg' => 'dc17583d7073f6a7e269e9a72b8d733c', './themes/default/css/style.css' => 'f92d7b18caf72f685e65e101fcf1aba6', + './themes/default/css/bootstrap.css' => 'e82686cdcac3d854553ec8827eb15ca0', './themes/default/css/chart.css' => '78bf9d159067f20c5e3fc6adf7762f1c', './themes/default/css/print.css' => '91228fdf0a95726bfbb6f854b2ac3e01', './themes/default/css/wizard.css' => 'bca3558b4758b9127a5073782f625336', @@ -6525,7 +6595,7 @@ $md5_string = array ( './themes/Sugar5/images/select.gif' => '2090e9761478fb6bee48c197b0f102dc', './themes/Sugar5/images/arrow_down.gif' => '7ae60aa70170713428e265b1cc695291', './themes/Sugar5/themedef.php' => '79f66d3ad564f057ab233f595c84f28c', - './themes/Sugar5/css/style.css' => '62ae2e32940ecfb5ff90442905e93ad9', + './themes/Sugar5/css/style.css' => '4fb70bd8ac2a9243b3bb28f6fe55cacc', './themes/Sugar5/css/chart.css' => '78bf9d159067f20c5e3fc6adf7762f1c', './themes/Sugar5/css/print.css' => 'c00fb2d3011318e43c4b1332080d1698', './themes/Sugar5/css/yui.css' => '45d099cc32f4ea1cf99817b9374e0566', @@ -6542,6 +6612,7 @@ $md5_string = array ( './jssource/src_files/themes/Sugar5/js/style.js' => '0b1dadc882afed3eb7c0071ee19aa36d', './jssource/src_files/themes/default/js/style.js' => 'fdb215ecd8c10f81670747912c750d98', './jssource/src_files/modules/Home/about.js' => '5df96a1f221dfb3ca25650abe3c24eff', + './jssource/src_files/modules/Home/tour.js' => '2691f6e5c07481e902ede71c3d255b62', './jssource/src_files/modules/Currencies/EditView.js' => '83b17318ef591148bbc75e2aebb5c8d5', './jssource/src_files/modules/Administration/javascript/Async.js' => 'd0e7a85e67bde67980dad376c11f1221', './jssource/src_files/modules/Administration/javascript/Administration.js' => '8c7eb2c4bd0024ab3f020d84c58ef1d5', @@ -7354,16 +7425,18 @@ $md5_string = array ( './jssource/src_files/include/javascript/sugar_yui_overrides.js' => 'ac6afa48c7c53dd7a52fc0e812c54d4f', './jssource/src_files/include/javascript/cookie.js' => 'c4e6168195f22c5fbb1780a0745bde24', './jssource/src_files/include/javascript/popup_parent_helper.js' => 'c546e26584026b47054eecbcba234410', - './jssource/src_files/include/javascript/sugar_3.js' => 'f0b9d30c421eca4a9d8772c607351118', + './jssource/src_files/include/javascript/sugar_3.js' => '0770f4e0882a2cfade6a615768e1ceb3', './jssource/src_files/include/javascript/jquery.js' => '219073097031d9c1a95a1291d66f3a10', './jssource/src_files/include/javascript/sugar_connection_event_listener.js' => 'e38a0e0155991cbc8fabaa59bcb1b705', - './jssource/src_files/include/javascript/jsclass_async.js' => '9f9bb812b962be782121ec32cc68fe36', + './jssource/src_files/include/javascript/jsclass_async.js' => '95072f5177e01c78662f14596255402e', './jssource/src_files/include/javascript/quickCompose.js' => '11a2d042c773ecec8afd0a26137265c7', './jssource/src_files/include/javascript/menu.js' => 'd5b3b0de4b7cd4c2c10eef2e5f2977a7', './jssource/src_files/include/javascript/sugarwidgets/SugarYUILoader.js' => '083ca4051ecfd7eab9d6af2ddb36631a', './jssource/src_files/include/javascript/sugarwidgets/SugarYUIWidgets.js' => 'a193587d4730e306026088f7af523186', + './jssource/src_files/include/javascript/tour.js' => 'e03bc1668821d6e530e56f25378a70ac', './jssource/src_files/include/javascript/importWizard.js' => '478fda5d88121d744272acbe6fea5924', './jssource/src_files/include/javascript/jsclass_base.js' => '68f095cc1d1f016ae276854e582d78ed', + './jssource/src_files/include/EditView/Panels.js' => '4d6c7ed97648d7f89391915d6da69554', './jssource/src_files/include/ytree/TreeView/HTMLNode.js' => '80d3d7b998e77999da2cd4fb0168ab68', './jssource/src_files/include/ytree/TreeView/RootNode.js' => '84e59f27cdc5626482e0aab754afaaee', './jssource/src_files/include/ytree/TreeView/TaskNode.js' => 'eb7b39df715ad52c70168cf8aae0d826', @@ -7393,7 +7466,7 @@ $md5_string = array ( './jssource/minify_utils.php' => 'f8041fdf57fcd09505abcb86e7f2f7b4', './jssource/jsmin.php' => 'a829ac7a2fb59907c67e8c7b5eb7ef50', './jssource/Minifier.php' => '715c5d44e0fc304857e1f466fc20533e', - './jssource/JSGroupings.php' => '226f05d0c0dcdc69ec23fa1494ed4776', + './jssource/JSGroupings.php' => '7edc1a425ce67bedc94475775e6783fb', './crossdomain.xml' => '6922829b24bd53b718b25bb5066664df', './upload/index.html' => '330a1eedb7f47535b37c1159ef805ec1', './acceptDecline.php' => '85460f31e0ebcc776ee1d15087b10e1a', @@ -7428,19 +7501,19 @@ $md5_string = array ( './install/installSystemCheck.php' => '102e9133c3a6e068e78d1f0c8a78e99d', './install/register.php' => 'e330b29cb54c42d55a0cc8d9a433c9b0', './install/TeamDemoData.php' => 'c68371a9b0a56c01295eefe7c7e24f72', - './install/language/en_us.lang.php' => '1ede5390d19632885f6fb19031137ff9', + './install/language/en_us.lang.php' => 'b1863510a31c56464730b50323f7c0b9', './install/seed_data/quotes_SeedData.php' => 'ec21dd960d685aab758ff501b31bd4fd', './install/seed_data/Advanced_Password_SeedData.php' => '6570caa9b6f9802427211ddb3f9f5066', './install/licensePrint.php' => 'd574f1f71eeaf3dc4be9e12f3d5b43e9', './install/license.php' => '00d8b0f04104eaa3cab95f1d1b26fb33', './install/installType.php' => 'f5b3025e3996ad16b8218d3b1424e389', './install/download_modules.php' => 'a1625e32936a669709b617a609c5a7ba', - './download.php' => 'cdc2271aff5d9893e95168501eac0d31', + './download.php' => '24c458db455efd69a3f135ace60ea02c', './campaign_trackerv2.php' => 'd474548736ceaf4275064094e5aa798b', './install.php' => 'a4e2e1c845b63962dfa89cd8ff50c9f7', './soap/SoapDeprecated.php' => '309e512eb7592c910a824f991869c4b4', './soap/SoapError.php' => 'dff0c6fc02f66fbb4f86a91691ee300e', - './soap/SoapHelperFunctions.php' => '6c048484d622dabb8591c5ff02a6e420', + './soap/SoapHelperFunctions.php' => '0cda7e6e106832d2b04dc2ce607ea614', './soap/SoapPortalHelper.php' => '302d5e90cf56d708b6d3f087fec2e72f', './soap/SoapSugarUsers.php' => '139d0b860d8efdae004c89c28417e96c', './soap/SoapStudio.php' => '0fd81758942a52940c119f3afa134fcd', diff --git a/include/DetailView/DetailView.tpl b/include/DetailView/DetailView.tpl index 98a47645..e7d2c000 100644 --- a/include/DetailView/DetailView.tpl +++ b/include/DetailView/DetailView.tpl @@ -47,17 +47,28 @@ class="yui-navset detailview_tabs" {{counter name="tabCount" start=-1 print=false assign="tabCount"}} {{/if}}
{{* Loop through all top level panels first *}} {{counter name="panelCount" print=false start=0 assign="panelCount"}} +{{counter name="tabCount" start=-1 print=false assign="tabCount"}} {{foreach name=section from=$sectionPanels key=label item=panel}} {{assign var='panel_id' value=$panelCount}} -
+{{capture name=label_upper assign=label_upper}}{{$label|upper}}{{/capture}} + {{if (isset($tabDefs[$label_upper].newTab) && $tabDefs[$label_upper].newTab == true)}} + {{counter name="tabCount" print=false}} + {{if $tabCount != 0}}
{{/if}} +
+ {{/if}} +
{counter name="panelFieldCount" start=0 print=false assign="panelFieldCount"} {{* Print out the panel title if one exists*}} @@ -67,11 +78,32 @@ class="yui-navset detailview_tabs" {sugar_include type='php' file='{{$panel}}'} {{else}} - {{if !empty($label) && !is_int($label) && $label != 'DEFAULT' && !$useTabs}} -

{sugar_translate label='{{$label}}' module='{{$module}}'}

- {{/if}} + {{if !empty($label) && !is_int($label) && $label != 'DEFAULT' && (!isset($tabDefs[$label_upper].newTab) || (isset($tabDefs[$label_upper].newTab) && $tabDefs[$label_upper].newTab == false))}} +

+ + + + + {sugar_translate label='{{$label}}' module='{{$module}}'} + {{if ( isset($tabDefs[$label_upper].panelDefault) && $tabDefs[$label_upper].panelDefault == "collapsed" && isset($tabDefs[$label_upper].newTab) && $tabDefs[$label_upper].newTab == false) }} + {{assign var='panelState' value=$tabDefs[$label_upper].panelDefault}} + {{else}} + {{assign var='panelState' value="expanded"}} + {{/if}} + {{if isset($panelState) && $panelState == 'collapsed'}} + + {{else}} + + {{/if}} +

+ + {{/if}} {{* Print out the table data *}} - +
@@ -164,14 +196,22 @@ class="yui-navset detailview_tabs" {/if} {{/foreach}}
+ {{if !empty($label) && !is_int($label) && $label != 'DEFAULT' && (!isset($tabDefs[$label_upper].newTab) || (isset($tabDefs[$label_upper].newTab) && $tabDefs[$label_upper].newTab == false))}} + + {{/if}} {{/if}}
-{if $panelFieldCount == 0 && !$useTabs} +{if $panelFieldCount == 0} {/if} {{/foreach}} -
+{{if $useTabs}} + +{{/if}} + + + {{include file=$footerTpl}} {{if $useTabs}} diff --git a/include/DetailView/header.tpl b/include/DetailView/header.tpl index f3b4fcdc..71bf7d09 100644 --- a/include/DetailView/header.tpl +++ b/include/DetailView/header.tpl @@ -39,8 +39,7 @@ {{if $preForm}} {{$preForm}} {{/if}} - - + {{else}} + + {{/if}} + + {{/if}} + + {{assign var='rowCount' value=0}} {{assign var='ACCKEY' value=''}} @@ -121,10 +147,10 @@ class="yui-navset" {{elseif isset($colData.field.label)}} {capture name="label" assign="label"}{sugar_translate label='{{$colData.field.label}}' module='{{$module}}'}{/capture} - + {$label|strip_semicolon}: {{elseif isset($fields[$colData.field.name])}} {capture name="label" assign="label"}{sugar_translate label='{{$fields[$colData.field.name].vname}}' module='{{$module}}'}{/capture} - + {$label|strip_semicolon}: {{else}}   {{/if}} @@ -213,6 +239,9 @@ class="yui-navset" {/if} {{/foreach}}
+{{if !empty($label) && !is_int($label) && $label != 'DEFAULT' && $showSectionPanelsTitles && (!isset($tabDefs[$label_upper].newTab) || (isset($tabDefs[$label_upper].newTab) && $tabDefs[$label_upper].newTab == false)) && $view != "QuickCreate"}} + +{{/if}} {{/if}} @@ -240,4 +269,10 @@ window.onbeforeunload = function () {ldelim} return disableOnUnloadEditView(); { {{else}} window.onbeforeunload = function () {ldelim} return onUnloadEditView(); {rdelim}; {{/if}} +// bug 55468 -- IE is too aggressive with onUnload event +if ($.browser.msie) {ldelim} +$(document).ready(function() {ldelim} + $(".collapseLink,.expandLink").click(function (e) {ldelim} e.preventDefault(); {rdelim}); + {rdelim}); +{rdelim} diff --git a/include/EditView/EditView2.php b/include/EditView/EditView2.php index 1c7de96b..9e4e84d9 100644 --- a/include/EditView/EditView2.php +++ b/include/EditView/EditView2.php @@ -595,7 +595,7 @@ class EditView $this->th->ss->assign('returnId', $this->returnId); $this->th->ss->assign('isDuplicate', $this->isDuplicate); $this->th->ss->assign('def', $this->defs); - $this->th->ss->assign('useTabs', isset($this->defs['templateMeta']['useTabs']) ? $this->defs['templateMeta']['useTabs'] : false); + $this->th->ss->assign('useTabs', isset($this->defs['templateMeta']['useTabs']) && isset($this->defs['templateMeta']['tabDefs']) ? $this->defs['templateMeta']['useTabs'] : false); $this->th->ss->assign('maxColumns', isset($this->defs['templateMeta']['maxColumns']) ? $this->defs['templateMeta']['maxColumns'] : 2); $this->th->ss->assign('module', $this->module); $this->th->ss->assign('headerTpl', isset($this->defs['templateMeta']['form']['headerTpl']) ? $this->defs['templateMeta']['form']['headerTpl'] : 'include/' . $this->view . '/header.tpl'); @@ -604,6 +604,7 @@ class EditView $this->th->ss->assign('bean', $this->focus); $this->th->ss->assign('isAuditEnabled', $this->focus->is_AuditEnabled()); $this->th->ss->assign('gridline',$current_user->getPreference('gridline') == 'on' ? '1' : '0'); + $this->th->ss->assign('tabDefs', isset($this->defs['templateMeta']['tabDefs']) ? $this->defs['templateMeta']['tabDefs'] : false); $this->th->ss->assign('VERSION_MARK', getVersionedPath('')); global $js_custom_version; diff --git a/include/EditView/Panels.js b/include/EditView/Panels.js new file mode 100644 index 00000000..1425b78b --- /dev/null +++ b/include/EditView/Panels.js @@ -0,0 +1,39 @@ +/********************************************************************************* + * SugarCRM Community Edition is a customer relationship management program developed by + * SugarCRM, Inc. Copyright (C) 2004-2012 SugarCRM Inc. + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU Affero General Public License version 3 as published by the + * Free Software Foundation with the addition of the following permission added + * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK + * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY + * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more + * details. + * + * You should have received a copy of the GNU Affero General Public License along with + * this program; if not, see http://www.gnu.org/licenses or write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA. + * + * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road, + * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com. + * + * The interactive user interfaces in modified source and object code versions + * of this program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU Affero General Public License version 3. + * + * In accordance with Section 7(b) of the GNU Affero General Public License version 3, + * these Appropriate Legal Notices must retain the display of the "Powered by + * SugarCRM" logo. If the display of the logo is not reasonably feasible for + * technical reasons, the Appropriate Legal Notices must display the words + * "Powered by SugarCRM". + ********************************************************************************/ +function initPanel(id,state){panelId='detailpanel_'+id;expandPanel(id);if(state=='collapsed'){collapsePanel(id);}} +function expandPanel(id){var panelId='detailpanel_'+id;document.getElementById(panelId).className=document.getElementById(panelId).className.replace(/(expanded|collapsed)/ig,'')+' expanded';} +function collapsePanel(id){var panelId='detailpanel_'+id;document.getElementById(panelId).className=document.getElementById(panelId).className.replace(/(expanded|collapsed)/ig,'')+' collapsed';} +function setCollapseState(mod,panel,isCollapsed){var sugar_panel_collase=Get_Cookie("sugar_panel_collase");if(sugar_panel_collase==null){sugar_panel_collase={};}else{sugar_panel_collase=YAHOO.lang.JSON.parse(sugar_panel_collase);} +sugar_panel_collase[mod]=sugar_panel_collase[mod]||{};sugar_panel_collase[mod][panel]=isCollapsed;Set_Cookie('sugar_panel_collase',YAHOO.lang.JSON.stringify(sugar_panel_collase),30,'/','','');} \ No newline at end of file diff --git a/include/EditView/SubpanelQuickEdit.php b/include/EditView/SubpanelQuickEdit.php index a9d0f447..e4b2ac78 100644 --- a/include/EditView/SubpanelQuickEdit.php +++ b/include/EditView/SubpanelQuickEdit.php @@ -106,6 +106,11 @@ class SubpanelQuickEdit{ if(file_exists($viewEditSource) && !$proccessOverride) { include($viewEditSource); $c = $module . 'ViewEdit'; + + $customClass = 'Custom' . $c; + if(class_exists($customClass)) { + $c = $customClass; + } if(class_exists($c)) { $view = new $c; diff --git a/include/EditView/SugarVCR.php b/include/EditView/SugarVCR.php index 945f697b..9460336f 100644 --- a/include/EditView/SugarVCR.php +++ b/include/EditView/SugarVCR.php @@ -76,79 +76,80 @@ return $menu; } - function menu($module, $offset, $isAuditEnabled, $saveAndContinue = false ){ - $html_text = ""; - if($offset < 0) { - $offset = 0; - } - //this check if require in cases when you visit the edit view before visiting that modules list view. - //you can do this easily either from home, activities or sitemap. - $stored_vcr_query=SugarVCR::retrieve($module); - if(!empty($_REQUEST['record']) and !empty($stored_vcr_query) and isset($_REQUEST['offset']) and (empty($_REQUEST['isDuplicate']) or $_REQUEST['isDuplicate'] == 'false')){ // bug 15893 - only show VCR if called as an element in a set of records - //syncing with display offset; - $offset++; - $action = (!empty($_REQUEST['action']) ? $_REQUEST['action'] : 'EditView'); - //$html_text .= "\n"; - //$html_text .= "\n"; - $html_text .= "\n"; - - $list_URL = 'index.php?action=index&module='.$module; - $current_page = floor($offset / 20) * 20; - $list_URL .= '&offset='.$current_page; - - $menu = SugarVCR::play($module, $offset); - if($saveAndContinue){ - if(!empty($menu['NEXT'])){ - $return_action = 'EditView'; - $return_id = $menu['NEXT']; - $list_URL = ajaxLink('index.php?action=EditView&module='.$module.'&record='.$return_id.'&offset='.($offset+1)); - $list_link = ""; - }else - $list_link = ""; - }else - $list_link = ""; - - $previous_link = ""; - $next_link = ""; - if(!empty($menu['PREV'])) { - //$previous_link = "".SugarThemeRegistry::current()->getImage("previous","border='0' align='absmiddle'",null,null,'.gif',$GLOBALS['app_strings']['LNK_LIST_PREVIOUS']).' '.$GLOBALS['app_strings']['LNK_LIST_PREVIOUS'].""; - - $href = ajaxLink("index.php?module=$module&action=$action&offset=".($offset-1)."&record=".$menu['PREV']); - $previous_link = ""; - - } - else - $previous_link = ""; - - - if(!empty($menu['NEXT'])) { - //$next_link = "".$GLOBALS['app_strings']['LNK_LIST_NEXT'].' '.SugarThemeRegistry::current()->getImage("next","border='0' align='absmiddle'",null,null,'.gif',$GLOBALS['app_strings']['LNK_LIST_NEXT']).""; - - $href = ajaxLink("index.php?module=$module&action=$action&offset=".($offset+1)."&record=".$menu['NEXT']); - $next_link = ""; - - } - else - $next_link = ""; - - - if(!empty($_SESSION[$module. 'total'])){ - $count = $offset .' '. $GLOBALS['app_strings']['LBL_LIST_OF'] . ' ' . $_SESSION[$module. 'total']; - if(!empty($GLOBALS['sugar_config']['disable_count_query']) - && ( ($_SESSION[$module. 'total']-1) % $GLOBALS['sugar_config']['list_max_entries_per_page'] == 0 ) ) { - $count .= '+'; + function menu($module, $offset, $isAuditEnabled, $saveAndContinue = false ){ + $html_text = ""; + if ($offset < 0) + { + $offset = 0; + } + + //this check if require in cases when you visit the edit view before visiting that modules list view. + //you can do this easily either from home, activities or sitemap. + $stored_vcr_query = SugarVCR::retrieve($module); + + // bug 15893 - only show VCR if called as an element in a set of records + if (!empty($_REQUEST['record']) and !empty($stored_vcr_query) and isset($_REQUEST['offset']) and (empty($_REQUEST['isDuplicate']) or $_REQUEST['isDuplicate'] == 'false')) + { + //syncing with display offset; + $offset ++; + $action = (!empty($_REQUEST['action']) ? $_REQUEST['action'] : 'EditView'); + + $menu = SugarVCR::play($module, $offset); + + $list_link = ''; + if ($saveAndContinue && !empty($menu['NEXT'])) + { + $list_link = ajaxLink('index.php?action=' . $action . '&module=' . $module . '&record=' . $menu['NEXT'] . '&offset=' . ($offset + 1)); + } + + $previous_link = ""; + if (!empty($menu['PREV'])) + { + $previous_link = ajaxLink('index.php?module=' . $module . '&action=' . $action . '&offset=' . ($offset - 1) . '&record=' . $menu['PREV']); + } + + $next_link = ""; + if (!empty($menu['NEXT'])) + { + $next_link = ajaxLink('index.php?module=' . $module . '&action=' . $action . '&offset=' . ($offset + 1) . '&record=' . $menu['NEXT']); + } + + $ss = new Sugar_Smarty(); + $ss->assign('app_strings', $GLOBALS['app_strings']); + $ss->assign('module', $module); + $ss->assign('action', $action); + $ss->assign('menu', $menu); + $ss->assign('list_link', $list_link); + $ss->assign('previous_link', $previous_link); + $ss->assign('next_link', $next_link); + + $ss->assign('offset', $offset); + $ss->assign('total', ''); + $ss->assign('plus', ''); + + if (!empty($_SESSION[$module . 'total'])) + { + $ss->assign('total', $_SESSION[$module . 'total']); + if ( + !empty($GLOBALS['sugar_config']['disable_count_query']) + && (($_SESSION[$module. 'total']-1) % $GLOBALS['sugar_config']['list_max_entries_per_page'] == 0) + ) + { + $ss->assign('plus', '+'); } - }else{ - $count = $offset; - } - $html_text .= ""; - - - - $html_text .= "
".$list_link."    ".$previous_link."  (".$count.")  ".$next_link."  
";//"; - } - return $html_text; - } + } + + if (is_file('custom/include/EditView/SugarVCR.tpl')) + { + $html_text .= $ss->fetch('custom/include/EditView/SugarVCR.tpl'); + } + else + { + $html_text .= $ss->fetch('include/EditView/SugarVCR.tpl'); + } + } + return $html_text; + } function record($module, $offset){ $GLOBALS['log']->debug('SUGARVCR is recording more records'); diff --git a/include/EditView/SugarVCR.tpl b/include/EditView/SugarVCR.tpl new file mode 100644 index 00000000..f422fa1a --- /dev/null +++ b/include/EditView/SugarVCR.tpl @@ -0,0 +1,73 @@ +{* +/********************************************************************************* + * SugarCRM Community Edition is a customer relationship management program developed by + * SugarCRM, Inc. Copyright (C) 2004-2012 SugarCRM Inc. + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU Affero General Public License version 3 as published by the + * Free Software Foundation with the addition of the following permission added + * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK + * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY + * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more + * details. + * + * You should have received a copy of the GNU Affero General Public License along with + * this program; if not, see http://www.gnu.org/licenses or write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA. + * + * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road, + * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com. + * + * The interactive user interfaces in modified source and object code versions + * of this program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU Affero General Public License version 3. + * + * In accordance with Section 7(b) of the GNU Affero General Public License version 3, + * these Appropriate Legal Notices must retain the display of the "Powered by + * SugarCRM" logo. If the display of the logo is not reasonably feasible for + * technical reasons, the Appropriate Legal Notices must display the words + * "Powered by SugarCRM". + ********************************************************************************/ + +*} + + + + +
+ {if !empty($list_link)} + +      + {/if} + + {if !empty($previous_link)} + + {else} + + {/if} +    + ({$offset}{if !empty($total)} {$app_strings.LBL_LIST_OF} {$total}{$plus}{/if}) +    + {if !empty($next_link)} + + {else} + + {/if} + +    +
diff --git a/include/EditView/header.tpl b/include/EditView/header.tpl index 800588d7..e7ca91a7 100644 --- a/include/EditView/header.tpl +++ b/include/EditView/header.tpl @@ -35,7 +35,6 @@ ********************************************************************************/ *} - {assign var="currentModule" value = $pageData.bean.moduleDir} {assign var="singularModule" value = $moduleListSingular.$currentModule} +{assign var="moduleName" value = $moduleList.$currentModule} {assign var="hideTable" value=false} {if count($data) == 0} @@ -77,7 +78,7 @@ {$APP.MSG_EMPTY_LIST_VIEW_NO_RESULTS|replace:"":$createLink|replace:"":$importLink}

- {$APP.MSG_EMPTY_LIST_VIEW_NO_RESULTS_SUBMSG|replace:"":$pageData.bean.moduleName|replace:"":$helpLink} + {$APP.MSG_EMPTY_LIST_VIEW_NO_RESULTS_SUBMSG|replace:"":$moduleName|replace:"":$helpLink}

{elseif $query == "-advanced_search"}

diff --git a/include/ListView/ListViewSmarty.php b/include/ListView/ListViewSmarty.php index b498b324..53de3b9e 100644 --- a/include/ListView/ListViewSmarty.php +++ b/include/ListView/ListViewSmarty.php @@ -203,6 +203,7 @@ class ListViewSmarty extends ListViewDisplay{ if(!$this->should_process) return $GLOBALS['app_strings']['LBL_SEARCH_POPULATE_ONLY']; global $app_strings, $sugar_version, $sugar_flavor, $server_unique_key, $currentModule, $app_list_strings; $this->ss->assign('moduleListSingular', $app_list_strings["moduleListSingular"]); + $this->ss->assign('moduleList', $app_list_strings['moduleList']); $this->ss->assign('data', $this->data['data']); $this->ss->assign('query', $this->data['query']); $this->ss->assign('sugar_info', array("sugar_version" => $sugar_version, diff --git a/include/MySugar/tpls/MySugar.tpl b/include/MySugar/tpls/MySugar.tpl index 7831bc33..408f6fc2 100644 --- a/include/MySugar/tpls/MySugar.tpl +++ b/include/MySugar/tpls/MySugar.tpl @@ -194,3 +194,4 @@ mySugarLoader.insert(); + diff --git a/include/SearchForm/SearchForm2.php b/include/SearchForm/SearchForm2.php index a103c306..a72587cb 100644 --- a/include/SearchForm/SearchForm2.php +++ b/include/SearchForm/SearchForm2.php @@ -1021,21 +1021,15 @@ require_once('include/EditView/EditView2.php'); //check to see if this is a universal search OR the field has db_concat_fields set in vardefs, AND the field name is "last_name" //BUG 45709: Tasks Advanced Search: Contact Name field does not return matches on full names //Frank: Adding Surabhi's fix back which seem to have gone missing in CottonCandy merge - if(($UnifiedSearch || !empty($this->seed->field_name_map[$field]['db_concat_fields'])) && (strpos($db_field, 'last_name') !== false) || strpos($db_field, 'name_2') !== false){ + if(($UnifiedSearch || !empty($this->seed->field_name_map[$field]['db_concat_fields'])) && strpos($db_field, 'last_name') !== false){ //split the string value, and the db field name $string = explode(' ', $field_value); $column_name = explode('.', $db_field); //when a search is done with a space, we concatenate and search against the full name. if(count($string)>1){ - //add where clause against concatenated field - $first_field = $parms['db_field'][0]; - $second_field = $parms['db_field'][1]; - $first_db_fields = explode('.', $first_field); - $second_db_fields = explode('.', $second_field); - if(count($first_db_fields)==2) $first_field = $first_db_fields[1]; - if(count($second_db_fields)==2) $second_field = $second_db_fields[1]; - $where .= $this->seed->db->concat($column_name[0],array($first_field,$second_field)) . " LIKE ".$this->seed->db->quoted($field_value.'%'); - $where .= ' OR ' . $this->seed->db->concat($column_name[0],array($second_field,$first_field)) . " LIKE ".$this->seed->db->quoted($field_value.'%'); + //add where clause against concatenated fields + $where .= $this->seed->db->concat($column_name[0],array('first_name','last_name')) . " LIKE ".$this->seed->db->quoted($field_value.'%'); + $where .= ' OR ' . $this->seed->db->concat($column_name[0],array('last_name','first_name')) . " LIKE ".$this->seed->db->quoted($field_value.'%'); }else{ //no space was found, add normal where clause $where .= $db_field . " like ".$this->seed->db->quoted(sql_like_string($field_value, $like_char)); diff --git a/include/SubPanel/SubPanelTiles.php b/include/SubPanel/SubPanelTiles.php index 4da8a151..d457ca47 100644 --- a/include/SubPanel/SubPanelTiles.php +++ b/include/SubPanel/SubPanelTiles.php @@ -297,8 +297,16 @@ if(document.DetailView != null && $div_display = $default_div_display; $cookie_name = $tab . '_v'; + if (isset($thisPanel->_instance_properties['collapsed']) && $thisPanel->_instance_properties['collapsed']) + { + $div_display = 'none'; + } + if(isset($div_cookies[$cookie_name])){ - $div_display = $div_cookies[$cookie_name]; + //If defaultSubPanelExpandCollapse is set, ignore the cookie that remembers whether the panel is expanded or collapsed. + //To be used with the above 'collapsed' metadata setting so they will always be set the same when the page is loaded. + if(!isset($sugar_config['defaultSubPanelExpandCollapse']) || $sugar_config['defaultSubPanelExpandCollapse'] == false) + $div_display = $div_cookies[$cookie_name]; } if(!empty($sugar_config['hide_subpanels'])){ $div_display = 'none'; diff --git a/include/SugarCharts/Jit/JitReports.php b/include/SugarCharts/Jit/JitReports.php index b0d7a4aa..ba09f0ed 100644 --- a/include/SugarCharts/Jit/JitReports.php +++ b/include/SugarCharts/Jit/JitReports.php @@ -56,6 +56,26 @@ class JitReports extends Jit { return $total; } + /** + * Method checks is our dataset from currency field or not + * + * @param array $dataset of chart + * @return bool is currency + */ + public function isCurrencyReportGroupTotal(array $dataset) + { + $isCurrency = true; + foreach ($dataset as $value) + { + if (empty($value['numerical_is_currency'])) + { + $isCurrency = false; + break; + } + } + return $isCurrency; + } + function processReportData($dataset, $level=1, $first=false){ $data = ''; @@ -133,7 +153,9 @@ class JitReports extends Jit { return $data; } - function xmlDataReportChart(){ + function xmlDataReportChart() + { + global $app_strings; $data = ''; // correctly process the first row $first = true; @@ -141,12 +163,26 @@ class JitReports extends Jit { $total = $this->calculateReportGroupTotal($dataset); $this->checkYAxis($total); - + $data .= $this->tab('', 2); $data .= $this->tabValue('title',$key, 3); $data .= $this->tabValue('value',$total, 3); - $data .= $this->tabValue('label',$total, 3); - $data .= $this->tab('', 3); + + $label = $total; + if ($this->isCurrencyReportGroupTotal($dataset)) + {; + $label = currency_format_number($total, array( + 'currency_symbol' => $this->currency_symbol, + 'decimals' => ($this->chart_properties['thousands'] ? 0 : null) + )); + } + if ($this->chart_properties['thousands']) + { + $label .= $app_strings['LBL_THOUSANDS_SYMBOL']; + } + $data .= $this->tabValue('label', $label, 3); + + $data .= $this->tab('', 3); if ((isset($dataset[$total]) && $total != $dataset[$total]['numerical_value']) || !array_key_exists($key, $dataset)){ $data .= $this->processReportData($dataset, 4, $first); @@ -219,7 +255,7 @@ class JitReports extends Jit { parent::display($name, $xmlFile, $width, $height, $resize=false); return $this->ss->fetch('include/SugarCharts/Jit/tpls/chart.tpl'); + + } } - -?> \ No newline at end of file diff --git a/include/SugarCharts/JsChart.php b/include/SugarCharts/JsChart.php index aa29d113..fc8fd8f8 100644 --- a/include/SugarCharts/JsChart.php +++ b/include/SugarCharts/JsChart.php @@ -242,11 +242,11 @@ class JsChart extends SugarChart { } function buildProperties($xmlstr) { - $content = $this->tab("'properties': [\n",1); + $content = $this->tab("\"properties\": [\n",1); $properties = array(); $xml = new SimpleXMLElement($xmlstr); foreach($xml->properties->children() as $property) { - $properties[] = $this->tab("'".$property->getName()."':"."'".$this->processSpecialChars($property)."'",2); + $properties[] = $this->tab("\"".$property->getName()."\":"."\"".$this->processSpecialChars($property)."\"",2); } $content .= $this->tab("{\n",1); $content .= join(",\n",$properties)."\n"; @@ -256,11 +256,11 @@ class JsChart extends SugarChart { } function buildLabelsBarChartStacked($xmlstr) { - $content = $this->tab("'label': [\n",1); + $content = $this->tab("\"label\": [\n",1); $labels = array(); $xml = new SimpleXMLElement($xmlstr); foreach($xml->data->group[0]->subgroups->group as $group) { - $labels[] = $this->tab("'".$this->processSpecialChars($group->title)."'",2); + $labels[] = $this->tab("\"".$this->processSpecialChars($group->title)."\"",2); } $content .= join(",\n",$labels)."\n"; $content .= $this->tab("],\n",1); @@ -277,11 +277,11 @@ class JsChart extends SugarChart { return $this->buildLabelsBarChartStacked($xmlstr); } - $content = $this->tab("'label': [\n",1); + $content = $this->tab("\"label\": [\n",1); $labels = array(); foreach($xml->data->group as $group) { - $labels[] = $this->tab("'".$this->processSpecialChars($group->title)."'",2); + $labels[] = $this->tab("\"".$this->processSpecialChars($group->title)."\"",2); } $labelStr = join(",\n",$labels)."\n"; $content .= $labelStr; @@ -290,31 +290,31 @@ class JsChart extends SugarChart { } function buildDataBarChartStacked($xmlstr) { - $content = $this->tab("'values': [\n",1); + $content = $this->tab("\"values\": [\n",1); $data = array(); $xml = new SimpleXMLElement($xmlstr); foreach($xml->data->group as $group) { $groupcontent = $this->tab("{\n",1); - $groupcontent .= $this->tab("'label': '".$this->processSpecialChars($group->title)."',\n",2); - $groupcontent .= $this->tab("'gvalue': '{$group->value}',\n",2); - $groupcontent .= $this->tab("'gvaluelabel': '{$group->label}',\n",2); + $groupcontent .= $this->tab("\"label\": \"".$this->processSpecialChars($group->title)."\",\n",2); + $groupcontent .= $this->tab("\"gvalue\": \"{$group->value}\",\n",2); + $groupcontent .= $this->tab("\"gvaluelabel\": \"{$group->label}\",\n",2); $subgroupValues = array(); $subgroupValueLabels = array(); $subgroupLinks = array(); foreach($group->subgroups->group as $subgroups) { $subgroupValues[] = $this->tab(($subgroups->value == "NULL") ? 0 : $subgroups->value,3); - $subgroupValueLabels[] = $this->tab("'".$this->processSpecialChars($subgroups->label)."'",3); - $subgroupLinks[] = $this->tab("'".$subgroups->link."'",3); + $subgroupValueLabels[] = $this->tab("\"".$this->processSpecialChars($subgroups->label)."\"",3); + $subgroupLinks[] = $this->tab("\"".$subgroups->link."\"",3); } $subgroupValuesStr = join(",\n",$subgroupValues)."\n"; $subgroupValueLabelsStr = join(",\n",$subgroupValueLabels)."\n"; $subgroupLinksStr = join(",\n",$subgroupLinks)."\n"; - $groupcontent .= $this->tab("'values': [\n".$subgroupValuesStr,2); + $groupcontent .= $this->tab("\"values\": [\n".$subgroupValuesStr,2); $groupcontent .= $this->tab("],\n",2); - $groupcontent .= $this->tab("'valuelabels': [\n".$subgroupValueLabelsStr,2); + $groupcontent .= $this->tab("\"valuelabels\": [\n".$subgroupValueLabelsStr,2); $groupcontent .= $this->tab("],\n",2); - $groupcontent .= $this->tab("'links': [\n".$subgroupLinksStr,2); + $groupcontent .= $this->tab("\"links\": [\n".$subgroupLinksStr,2); $groupcontent .= $this->tab("]\n",2); $groupcontent .= $this->tab("}",1); $data[] = $groupcontent; @@ -325,36 +325,36 @@ class JsChart extends SugarChart { } function buildDataBarChartGrouped($xmlstr) { - $content = $this->tab("'values': [\n",1); + $content = $this->tab("\"values\": [\n",1); $data = array(); $xml = new SimpleXMLElement($xmlstr); foreach($xml->data->group as $group) { $groupcontent = $this->tab("{\n",1); - $groupcontent .= $this->tab("'label': '".$this->processSpecialChars($group->title)."',\n",2); - $groupcontent .= $this->tab("'gvalue': '{$group->value}',\n",2); - $groupcontent .= $this->tab("'gvaluelabel': '{$group->label}',\n",2); + $groupcontent .= $this->tab("\"label\": \"".$this->processSpecialChars($group->title)."\",\n",2); + $groupcontent .= $this->tab("\"gvalue\": \"{$group->value}\",\n",2); + $groupcontent .= $this->tab("\"gvaluelabel\": \"{$group->label}\",\n",2); $subgroupValues = array(); $subgroupValueLabels = array(); $subgroupLinks = array(); $subgroupTitles = array(); foreach($group->subgroups->group as $subgroups) { $subgroupValues[] = $this->tab(($subgroups->value == "NULL") ? 0 : $subgroups->value,3); - $subgroupValueLabels[] = $this->tab("'".$subgroups->label."'",3); - $subgroupLinks[] = $this->tab("'".$subgroups->link."'",3); - $subgroupTitles[] = $this->tab("'".$this->processSpecialChars($subgroups->title)."'",3); + $subgroupValueLabels[] = $this->tab("\"".$subgroups->label."\"",3); + $subgroupLinks[] = $this->tab("\"".$subgroups->link."\"",3); + $subgroupTitles[] = $this->tab("\"".$this->processSpecialChars($subgroups->title)."\"",3); } $subgroupValuesStr = join(",\n",$subgroupValues)."\n"; $subgroupValueLabelsStr = join(",\n",$subgroupValueLabels)."\n"; $subgroupLinksStr = join(",\n",$subgroupLinks)."\n"; $subgroupTitlesStr = join(",\n",$subgroupTitles)."\n"; - $groupcontent .= $this->tab("'values': [\n".$subgroupValuesStr,2); + $groupcontent .= $this->tab("\"values\": [\n".$subgroupValuesStr,2); $groupcontent .= $this->tab("],\n",2); - $groupcontent .= $this->tab("'valuelabels': [\n".$subgroupValueLabelsStr,2); + $groupcontent .= $this->tab("\"valuelabels\": [\n".$subgroupValueLabelsStr,2); $groupcontent .= $this->tab("],\n",2); - $groupcontent .= $this->tab("'links': [\n".$subgroupLinksStr,2); + $groupcontent .= $this->tab("\"links\": [\n".$subgroupLinksStr,2); $groupcontent .= $this->tab("],\n",2); - $groupcontent .= $this->tab("'titles': [\n".$subgroupTitlesStr,2); + $groupcontent .= $this->tab("\"titles\": [\n".$subgroupTitlesStr,2); $groupcontent .= $this->tab("]\n",2); $groupcontent .= $this->tab("}",1); $data[] = $groupcontent; @@ -365,7 +365,7 @@ class JsChart extends SugarChart { } function buildDataBarChart($xmlstr) { - $content = $this->tab("'values': [\n",1); + $content = $this->tab("\"values\": [\n",1); $data = array(); $xml = new SimpleXMLElement($xmlstr); $groupcontent = ""; @@ -373,19 +373,19 @@ class JsChart extends SugarChart { foreach($xml->data->group as $group) { $groupcontent = $this->tab("{\n",1); - $groupcontent .= $this->tab("'label': [\n",2); - $groupcontent .= $this->tab("'".$this->processSpecialChars($group->title)."'\n",3); + $groupcontent .= $this->tab("\"label\": [\n",2); + $groupcontent .= $this->tab("\"".$this->processSpecialChars($group->title)."\"\n",3); $groupcontent .= $this->tab("],\n",2); - $groupcontent .= $this->tab("'values': [\n",2); + $groupcontent .= $this->tab("\"values\": [\n",2); $groupcontent .= $this->tab(($group->value == "NULL") ? 0 : $group->value."\n",3); $groupcontent .= $this->tab("],\n",2); if($group->label) { - $groupcontent .= $this->tab("'valuelabels': [\n",2); - $groupcontent .= $this->tab("'{$group->label}'\n",3); + $groupcontent .= $this->tab("\"valuelabels\": [\n",2); + $groupcontent .= $this->tab("\"{$group->label}\"\n",3); $groupcontent .= $this->tab("],\n",2); } - $groupcontent .= $this->tab("'links': [\n",2); - $groupcontent .= $this->tab("'{$group->link}'\n",3); + $groupcontent .= $this->tab("\"links\": [\n",2); + $groupcontent .= $this->tab("\"{$group->link}\"\n",3); $groupcontent .= $this->tab("]\n",2); $groupcontent .= $this->tab("}",1); $groupcontentArr[] = $groupcontent; @@ -396,11 +396,11 @@ class JsChart extends SugarChart { } function buildLabelsPieChart($xmlstr) { - $content = $this->tab("'label': [\n",1); + $content = $this->tab("\"label\": [\n",1); $labels = array(); $xml = new SimpleXMLElement($xmlstr); foreach($xml->data->group as $group) { - $labels[] = $this->tab("'".$this->processSpecialChars($group->title)."'",2); + $labels[] = $this->tab("\"".$this->processSpecialChars($group->title)."\"",2); } $labelStr = join(",\n",$labels)."\n"; $content .= $labelStr; @@ -410,7 +410,7 @@ class JsChart extends SugarChart { function buildDataPieChart($xmlstr) { - $content = $this->tab("'values': [\n",1); + $content = $this->tab("\"values\": [\n",1); $data = array(); $xml = new SimpleXMLElement($xmlstr); $groupcontent = ""; @@ -418,17 +418,17 @@ class JsChart extends SugarChart { foreach($xml->data->group as $group) { $groupcontent = $this->tab("{\n",1); - $groupcontent .= $this->tab("'label': [\n",2); - $groupcontent .= $this->tab("'".$this->processSpecialChars($group->title)."'\n",3); + $groupcontent .= $this->tab("\"label\": [\n",2); + $groupcontent .= $this->tab("\"".$this->processSpecialChars($group->title)."\"\n",3); $groupcontent .= $this->tab("],\n",2); - $groupcontent .= $this->tab("'values': [\n",2); + $groupcontent .= $this->tab("\"values\": [\n",2); $groupcontent .= $this->tab("{$group->value}\n",3); $groupcontent .= $this->tab("],\n",2); - $groupcontent .= $this->tab("'valuelabels': [\n",2); - $groupcontent .= $this->tab("'{$group->label}'\n",3); + $groupcontent .= $this->tab("\"valuelabels\": [\n",2); + $groupcontent .= $this->tab("\"{$group->label}\"\n",3); $groupcontent .= $this->tab("],\n",2); - $groupcontent .= $this->tab("'links': [\n",2); - $groupcontent .= $this->tab("'{$group->link}'\n",3); + $groupcontent .= $this->tab("\"links\": [\n",2); + $groupcontent .= $this->tab("\"{$group->link}\"\n",3); $groupcontent .= $this->tab("]\n",2); $groupcontent .= $this->tab("}",1); $groupcontentArr[] = $groupcontent; @@ -441,11 +441,11 @@ class JsChart extends SugarChart { } function buildLabelsGaugeChart($xmlstr) { - $content = $this->tab("'label': [\n",1); + $content = $this->tab("\"label\": [\n",1); $labels = array(); $xml = new SimpleXMLElement($xmlstr); foreach($xml->data->group as $group) { - $labels[] = $this->tab("'".$this->processSpecialChars($group->title)."'",2); + $labels[] = $this->tab("\"".$this->processSpecialChars($group->title)."\"",2); } $labelStr = join(",\n",$labels)."\n"; $content .= $labelStr; @@ -454,15 +454,15 @@ class JsChart extends SugarChart { } function buildDataGaugeChart($xmlstr) { - $content = $this->tab("'values': [\n",1); + $content = $this->tab("\"values\": [\n",1); $data = array(); $xml = new SimpleXMLElement($xmlstr); foreach($xml->data->group as $group) { $groupcontent = $this->tab("{\n",1); - $groupcontent .= $this->tab("'label': '".$this->processSpecialChars($group->title)."',\n",2); - $groupcontent .= $this->tab("'gvalue': '{$group->value}',\n",2); + $groupcontent .= $this->tab("\"label\": \"".$this->processSpecialChars($group->title)."\",\n",2); + $groupcontent .= $this->tab("\"gvalue\": \"{$group->value}\",\n",2); $finalComma = ($group->title != "GaugePosition") ? "," : ""; - $groupcontent .= $this->tab("'gvaluelabel': '{$group->label}'{$finalComma}\n",2); + $groupcontent .= $this->tab("\"gvaluelabel\": \"{$group->label}\"{$finalComma}\n",2); $subgroupTitles = array(); $subgroupValues = array(); $subgroupValueLabels = array(); @@ -470,26 +470,26 @@ class JsChart extends SugarChart { if(is_object($group->subgroups->group)) { foreach($group->subgroups->group as $subgroups) { - $subgroupTitles[] = $this->tab("'".$subgroups->title."'",3); + $subgroupTitles[] = $this->tab("\"".$subgroups->title."\"",3); //$subgroupValues[] = $this->tab($subgroups->value,3); $subgroupValues[] = $subgroups->value; - $subgroupValueLabels[] = $this->tab("'".$subgroups->label."'",3); - $subgroupLinks[] = $this->tab("'".$subgroups->link."'",3); + $subgroupValueLabels[] = $this->tab("\"".$subgroups->label."\"",3); + $subgroupLinks[] = $this->tab("\"".$subgroups->link."\"",3); } $subgroupTitlesStr = join(",\n",$subgroupTitles)."\n"; $subgroupValuesStr = join(",\n",$subgroupValues)."\n"; $subgroupValueLabelsStr = join(",\n",$subgroupValueLabels)."\n"; $subgroupLinksStr = join(",\n",$subgroupLinks)."\n"; - //$groupcontent .= $this->tab("'labels': [\n".$subgroupTitlesStr,2); + //$groupcontent .= $this->tab("\"labels\": [\n".$subgroupTitlesStr,2); //$groupcontent .= $this->tab("],\n",2); $val = ((int)$subgroupValues[1] == (int)$subgroupValues[0]) ? $this->tab($subgroupValues[1],3)."\n" : $this->tab($subgroupValues[1] - $subgroupValues[0],3)."\n"; - $groupcontent .= $this->tab("'values': [\n".$val,2); + $groupcontent .= $this->tab("\"values\": [\n".$val,2); $groupcontent .= $this->tab("],\n",2); - $groupcontent .= $this->tab("'valuelabels': [\n".$subgroupValueLabelsStr,2); + $groupcontent .= $this->tab("\"valuelabels\": [\n".$subgroupValueLabelsStr,2); $groupcontent .= $this->tab("]\n",2); - //$groupcontent .= $this->tab("'links': [\n".$subgroupLinksStr,2); + //$groupcontent .= $this->tab("\"links\": [\n".$subgroupLinksStr,2); //$groupcontent .= $this->tab("]\n",2); } @@ -520,12 +520,12 @@ class JsChart extends SugarChart { function buildChartColors() { - $content = $this->tab("'color': [\n",1); + $content = $this->tab("\"color\": [\n",1); $colorArr = array(); $xml = $this->getConfigProperties(); $colors = ($this->chartType == "gauge chart") ? $xml->gaugeChartElementColors->color : $xml->chartElementColors->color; foreach($colors as $color) { - $colorArr[] = $this->tab("'".str_replace("0x","#",$color)."'",2); + $colorArr[] = $this->tab("\"".str_replace("0x","#",$color)."\"",2); } $content .= join(",\n",$colorArr)."\n"; $content .= $this->tab("],\n",1); diff --git a/include/SugarCharts/SugarChart.php b/include/SugarCharts/SugarChart.php index 1d0a1d35..5149c120 100644 --- a/include/SugarCharts/SugarChart.php +++ b/include/SugarCharts/SugarChart.php @@ -133,13 +133,15 @@ class SugarChart { $this->data_set = $dataSet; } - function setProperties($title, $subtitle, $type, $legend='on', $labels='value', $print='on'){ - $this->chart_properties['title'] = $title; - $this->chart_properties['subtitle'] = $subtitle; - $this->chart_properties['type'] = $type; - $this->chart_properties['legend'] = $legend; - $this->chart_properties['labels'] = $labels; - } + function setProperties($title, $subtitle, $type, $legend='on', $labels='value', $print='on', $thousands = false) + { + $this->chart_properties['title'] = $title; + $this->chart_properties['subtitle'] = $subtitle; + $this->chart_properties['type'] = $type; + $this->chart_properties['legend'] = $legend; + $this->chart_properties['labels'] = $labels; + $this->chart_properties['thousands'] = $thousands; + } function setDisplayProperty($property, $value){ $this->chart_properties[$property] = $value; @@ -186,7 +188,6 @@ class SugarChart { // grab the property and value from the chart_properties variable foreach ($this->chart_properties as $key => $value){ - if(is_array($value)) continue; $properties .= $this->tab("<$key>$value",2); } @@ -761,7 +762,7 @@ class SugarChart { return $templateFile; } - + function getDashletScript($id,$xmlFile="") { $xmlFile = (!$xmlFile) ? $sugar_config['tmp_dir']. $current_user->id . '_' . $this->id . '.xml' : $xmlFile; diff --git a/include/SugarFields/Fields/Base/SugarFieldBase.php b/include/SugarFields/Fields/Base/SugarFieldBase.php index 43328ccd..ce73b067 100644 --- a/include/SugarFields/Fields/Base/SugarFieldBase.php +++ b/include/SugarFields/Fields/Base/SugarFieldBase.php @@ -321,10 +321,16 @@ class SugarFieldBase { $this->button = ''; $this->buttons = ''; $this->image = ''; - if ($twopass){ - $this->ss->left_delimiter = '{{'; - $this->ss->right_delimiter = '}}'; - } + if ($twopass) + { + $this->ss->left_delimiter = '{{'; + $this->ss->right_delimiter = '}}'; + } + else + { + $this->ss->left_delimiter = '{'; + $this->ss->right_delimiter = '}'; + } $this->ss->assign('parentFieldArray', $parentFieldArray); $this->ss->assign('vardef', $vardef); $this->ss->assign('tabindex', $tabindex); diff --git a/include/SugarFields/Fields/Multienum/WirelessDetailView.tpl b/include/SugarFields/Fields/Multienum/WirelessDetailView.tpl new file mode 100644 index 00000000..6d659b20 --- /dev/null +++ b/include/SugarFields/Fields/Multienum/WirelessDetailView.tpl @@ -0,0 +1,45 @@ +{* +/********************************************************************************* + * SugarCRM Community Edition is a customer relationship management program developed by + * SugarCRM, Inc. Copyright (C) 2004-2012 SugarCRM Inc. + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU Affero General Public License version 3 as published by the + * Free Software Foundation with the addition of the following permission added + * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK + * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY + * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more + * details. + * + * You should have received a copy of the GNU Affero General Public License along with + * this program; if not, see http://www.gnu.org/licenses or write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA. + * + * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road, + * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com. + * + * The interactive user interfaces in modified source and object code versions + * of this program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU Affero General Public License version 3. + * + * In accordance with Section 7(b) of the GNU Affero General Public License version 3, + * these Appropriate Legal Notices must retain the display of the "Powered by + * SugarCRM" logo. If the display of the logo is not reasonably feasible for + * technical reasons, the Appropriate Legal Notices must display the words + * "Powered by SugarCRM". + ********************************************************************************/ + +*} + +{if !empty($vardef.value) && ($vardef.value != '^^')} + + {multienum_to_array string=$vardef.value assign="vals"} + {foreach from=$vals item='item'} +

  • {$vardef.options.$item}
  • + {/foreach} +{/if} diff --git a/include/SugarFields/Fields/Multienum/WirelessEditView.tpl b/include/SugarFields/Fields/Multienum/WirelessEditView.tpl new file mode 100644 index 00000000..3b9e2f5c --- /dev/null +++ b/include/SugarFields/Fields/Multienum/WirelessEditView.tpl @@ -0,0 +1,42 @@ +{* +/********************************************************************************* + * SugarCRM Community Edition is a customer relationship management program developed by + * SugarCRM, Inc. Copyright (C) 2004-2012 SugarCRM Inc. + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU Affero General Public License version 3 as published by the + * Free Software Foundation with the addition of the following permission added + * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK + * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY + * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more + * details. + * + * You should have received a copy of the GNU Affero General Public License along with + * this program; if not, see http://www.gnu.org/licenses or write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA. + * + * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road, + * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com. + * + * The interactive user interfaces in modified source and object code versions + * of this program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU Affero General Public License version 3. + * + * In accordance with Section 7(b) of the GNU Affero General Public License version 3, + * these Appropriate Legal Notices must retain the display of the "Powered by + * SugarCRM" logo. If the display of the logo is not reasonably feasible for + * technical reasons, the Appropriate Legal Notices must display the words + * "Powered by SugarCRM". + ********************************************************************************/ + +*} + +{multienum_to_array string=$vardef.value default=$vardef.default assign="values"} + diff --git a/include/SugarObjects/templates/company/vardefs.php b/include/SugarObjects/templates/company/vardefs.php index cf7abe01..c3f3e0cd 100644 --- a/include/SugarObjects/templates/company/vardefs.php +++ b/include/SugarObjects/templates/company/vardefs.php @@ -322,6 +322,7 @@ $vardefs= array ( ), 'source' => 'non-db', 'studio' => array('editField' => true, 'searchview' => false), + 'full_text_search' => array('boost' => 3, 'index' => 'not_analyzed'), //bug 54567 ), 'email_addresses_primary' => diff --git a/include/SugarObjects/templates/person/vardefs.php b/include/SugarObjects/templates/person/vardefs.php index 64c82e06..6585b56d 100644 --- a/include/SugarObjects/templates/person/vardefs.php +++ b/include/SugarObjects/templates/person/vardefs.php @@ -213,7 +213,7 @@ $vardefs =array( 'group'=>'email1', 'merge_filter' => 'enabled', 'studio' => array('editField' => true, 'searchview' => false, 'popupsearch' => false), // bug 46859 - + 'full_text_search' => array('boost' => 3, 'index' => 'not_analyzed'), //bug 54567 ), 'email2' => array( diff --git a/include/SugarPHPMailer.php b/include/SugarPHPMailer.php index a48b9a6c..11c46ee8 100644 --- a/include/SugarPHPMailer.php +++ b/include/SugarPHPMailer.php @@ -407,4 +407,16 @@ eoq; return $connection; } // fn + /* + * overloads PHPMailer::PreSend() to allow for empty messages to go out. + */ + protected function PreSend() { + //check to see if message body is empty + if(empty($this->Body)){ + //PHPMailer will throw an error if the body is empty, so insert a blank space if body is empty + $this->Body = " "; + } + return parent::PreSend(); + } + } // end class definition diff --git a/include/TemplateHandler/TemplateHandler.php b/include/TemplateHandler/TemplateHandler.php index 120c643e..2f0f606d 100644 --- a/include/TemplateHandler/TemplateHandler.php +++ b/include/TemplateHandler/TemplateHandler.php @@ -388,8 +388,19 @@ class TemplateHandler { if ($view == "ConvertLead") { $field['name'] = $module . $field['name']; - if (!empty($field['id_name'])) - $field['id_name'] = $field['name'] . "_" . $field['id_name']; + if (isset($field['module']) && isset($field['id_name']) && substr($field['id_name'], -4) == "_ida") { + $lc_module = strtolower($field['module']); + $ida_suffix = "_".$lc_module.$lc_module."_ida"; + if (preg_match('/'.$ida_suffix.'$/', $field['id_name']) > 0) { + $field['id_name'] = $module . $field['id_name']; + } + else + $field['id_name'] = $field['name'] . "_" . $field['id_name']; + } + else { + if (!empty($field['id_name'])) + $field['id_name'] = $field['name'] . "_" . $field['id_name']; + } } $name = $qsd->form_name . '_' . $field['name']; @@ -403,13 +414,16 @@ class TemplateHandler { if($matches[0] == 'Campaigns') { $sqs_objects[$name] = $qsd->loadQSObject('Campaigns', 'Campaign', $field['name'], $field['id_name'], $field['id_name']); } else if($matches[0] == 'Users'){ - if($field['name'] == 'reports_to_name') + if($field['name'] == 'reports_to_name'){ $sqs_objects[$name] = $qsd->getQSUser('reports_to_name','reports_to_id'); - else { - if($view == "ConvertLead" || $field['name'] == 'created_by_name' || $field['name'] == 'modified_by_name') - $sqs_objects[$name] = $qsd->getQSUser($field['name'], $field['id_name']); - else - $sqs_objects[$name] = $qsd->getQSUser(); + // Bug #52994 : QuickSearch for a 1-M User relationship changes assigned to user + }elseif($field['name'] == 'assigned_user_name'){ + $sqs_objects[$name] = $qsd->getQSUser('assigned_user_name','assigned_user_id'); + } + else + { + $sqs_objects[$name] = $qsd->getQSUser($field['name'], $field['id_name']); + } } else if($matches[0] == 'Campaigns') { $sqs_objects[$name] = $qsd->loadQSObject('Campaigns', 'Campaign', $field['name'], $field['id_name'], $field['id_name']); @@ -453,6 +467,33 @@ class TemplateHandler { } else if($field['type'] == 'parent') { $sqs_objects[$name] = $qsd->getQSParent(); } //if-else + + // Bug 53949 - Captivea (sve) - Partial fix : Append metadata fields that are not already included in $sqs_objects array + // (for example with hardcoded modules before, metadata arrays are not taken into account in 6.4.x 6.5.x) + // As QuickSearchDefault methods are called at other places, this will not fix the SQS problem for everywhere, but it fixes it on Editview + + //merge populate_list && field_list with vardef + if (!empty($field['field_list']) && !empty($field['populate_list'])) { + for ($j=0; $jform_name . '_' . $field['field_list'][$j]; + $populate_list_item = $field['populate_list'][$j]; + $found = false; + for ($k=0; $k_get_column_alias($layout_def)); + $tmp_field_name = str_replace('_DAY_', '_DAYREAL_', $field_name); + if($tmp_field_name != $field_name && isset($layout_def['fields'][$tmp_field_name])) + { + return $timedate->to_display_date($layout_def['fields'][$tmp_field_name], true); + } + else + { + return parent:: displayListPlain($layout_def); + } } function & displayListyear(& $layout_def) { @@ -514,6 +523,17 @@ class SugarWidgetFieldDateTime extends SugarWidgetReportField return $this->reporter->db->convert($this->_get_column_select($layout_def), "date_format", array('%Y-%m'))."\n"; } + /** + * Select addon datetime field for "day" field in reports + * + * @param $layout_def array definition of new field + * @return string piece for creation "select" query + */ + function querySelectdayreal($layout_def) + { + return $this->reporter->db->convert($this->_get_column_select($layout_def), "date_format", array('%Y-%m-%d %H:%i:%s'))." ".$this->_get_column_alias($layout_def)."\n"; + } + function querySelectday($layout_def) { return $this->reporter->db->convert($this->_get_column_select($layout_def), "date_format", array('%Y-%m-%d'))." ".$this->_get_column_alias($layout_def)."\n"; diff --git a/include/generic/SugarWidgets/SugarWidgetReportField.php b/include/generic/SugarWidgets/SugarWidgetReportField.php index 5d880a32..8acaadc3 100644 --- a/include/generic/SugarWidgets/SugarWidgetReportField.php +++ b/include/generic/SugarWidgets/SugarWidgetReportField.php @@ -257,7 +257,7 @@ class SugarWidgetReportField extends SugarWidgetField if ( ! empty($layout_def['group_function']) && $layout_def['group_function']=='count') { - return $layout_def['table_alias'] . '__count'; + return 'count'; } if ( ! empty($layout_def['table_alias'])) diff --git a/include/globalControlLinks.php b/include/globalControlLinks.php index bd66c5b1..00ef66de 100644 --- a/include/globalControlLinks.php +++ b/include/globalControlLinks.php @@ -75,6 +75,7 @@ $global_control_links['help'] = array( 'submenu' => '' ); */ + $global_control_links['users'] = array( 'linkinfo' => array($app_strings['LBL_LOGOUT'] => 'index.php?module=Users&action=Logout'), 'submenu' => '' diff --git a/include/images/tour/FirstFrame.png b/include/images/tour/FirstFrame.png new file mode 100644 index 0000000000000000000000000000000000000000..ba7ef2ed2661459928acb085168fe88ffae98db8 GIT binary patch literal 9053 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 A6951J literal 0 HcmV?d00001 diff --git a/include/images/tour/arrow_ie.png b/include/images/tour/arrow_ie.png new file mode 100644 index 0000000000000000000000000000000000000000..2d73e353d2875e2fe480eae1966c12551247f99b GIT binary patch literal 19079 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 literal 0 HcmV?d00001 diff --git a/include/javascript/jquery/bootstrap.min.js b/include/javascript/jquery/bootstrap.min.js new file mode 100644 index 00000000..ffaefa69 --- /dev/null +++ b/include/javascript/jquery/bootstrap.min.js @@ -0,0 +1,6 @@ +/** +* Bootstrap.js by @fat & @mdo +* Copyright 2012 Twitter, Inc. +* http://www.apache.org/licenses/LICENSE-2.0.txt +*/ +!function(a){a(function(){"use strict",a.support.transition=function(){var b=document.body||document.documentElement,c=b.style,d=c.transition!==undefined||c.WebkitTransition!==undefined||c.MozTransition!==undefined||c.MsTransition!==undefined||c.OTransition!==undefined;return d&&{end:function(){var b="TransitionEnd";return a.browser.webkit?b="webkitTransitionEnd":a.browser.mozilla?b="transitionend":a.browser.opera&&(b="oTransitionEnd"),b}()}}()})}(window.jQuery),!function(a){"use strict";var b='[data-dismiss="alert"]',c=function(c){a(c).on("click",b,this.close)};c.prototype={constructor:c,close:function(b){function f(){e.trigger("closed").remove()}var c=a(this),d=c.attr("data-target"),e;d||(d=c.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),e=a(d),e.trigger("close"),b&&b.preventDefault(),e.length||(e=c.hasClass("alert")?c:c.parent()),e.trigger("close").removeClass("in"),a.support.transition&&e.hasClass("fade")?e.on(a.support.transition.end,f):f()}},a.fn.alert=function(b){return this.each(function(){var d=a(this),e=d.data("alert");e||d.data("alert",e=new c(this)),typeof b=="string"&&e[b].call(d)})},a.fn.alert.Constructor=c,a(function(){a("body").on("click.alert.data-api",b,c.prototype.close)})}(window.jQuery),!function(a){"use strict";var b=function(b,c){this.$element=a(b),this.options=a.extend({},a.fn.button.defaults,c)};b.prototype={constructor:b,setState:function(a){var b="disabled",c=this.$element,d=c.data(),e=c.is("input")?"val":"html";a+="Text",d.resetText||c.data("resetText",c[e]()),c[e](d[a]||this.options[a]),setTimeout(function(){a=="loadingText"?c.addClass(b).attr(b,b):c.removeClass(b).removeAttr(b)},0)},toggle:function(){var a=this.$element.parent('[data-toggle="buttons-radio"]');a&&a.find(".active").removeClass("active"),this.$element.toggleClass("active")}},a.fn.button=function(c){return this.each(function(){var d=a(this),e=d.data("button"),f=typeof c=="object"&&c;e||d.data("button",e=new b(this,f)),c=="toggle"?e.toggle():c&&e.setState(c)})},a.fn.button.defaults={loadingText:"loading..."},a.fn.button.Constructor=b,a(function(){a("body").on("click.button.data-api","[data-toggle^=button]",function(b){var c=a(b.target);c.hasClass("btn")||(c=c.closest(".btn")),c.button("toggle")})})}(window.jQuery),!function(a){"use strict";var b=function(b,c){this.$element=a(b),this.options=a.extend({},a.fn.carousel.defaults,c),this.options.slide&&this.slide(this.options.slide),this.options.pause=="hover"&&this.$element.on("mouseenter",a.proxy(this.pause,this)).on("mouseleave",a.proxy(this.cycle,this))};b.prototype={cycle:function(){return this.interval=setInterval(a.proxy(this.next,this),this.options.interval),this},to:function(b){var c=this.$element.find(".active"),d=c.parent().children(),e=d.index(c),f=this;if(b>d.length-1||b<0)return;return this.sliding?this.$element.one("slid",function(){f.to(b)}):e==b?this.pause().cycle():this.slide(b>e?"next":"prev",a(d[b]))},pause:function(){return clearInterval(this.interval),this.interval=null,this},next:function(){if(this.sliding)return;return this.slide("next")},prev:function(){if(this.sliding)return;return this.slide("prev")},slide:function(b,c){var d=this.$element.find(".active"),e=c||d[b](),f=this.interval,g=b=="next"?"left":"right",h=b=="next"?"first":"last",i=this;this.sliding=!0,f&&this.pause(),e=e.length?e:this.$element.find(".item")[h]();if(e.hasClass("active"))return;return!a.support.transition&&this.$element.hasClass("slide")?(this.$element.trigger("slide"),d.removeClass("active"),e.addClass("active"),this.sliding=!1,this.$element.trigger("slid")):(e.addClass(b),e[0].offsetWidth,d.addClass(g),e.addClass(g),this.$element.trigger("slide"),this.$element.one(a.support.transition.end,function(){e.removeClass([b,g].join(" ")).addClass("active"),d.removeClass(["active",g].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger("slid")},0)})),f&&this.cycle(),this}},a.fn.carousel=function(c){return this.each(function(){var d=a(this),e=d.data("carousel"),f=typeof c=="object"&&c;e||d.data("carousel",e=new b(this,f)),typeof c=="number"?e.to(c):typeof c=="string"||(c=f.slide)?e[c]():e.cycle()})},a.fn.carousel.defaults={interval:5e3,pause:"hover"},a.fn.carousel.Constructor=b,a(function(){a("body").on("click.carousel.data-api","[data-slide]",function(b){var c=a(this),d,e=a(c.attr("data-target")||(d=c.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,"")),f=!e.data("modal")&&a.extend({},e.data(),c.data());e.carousel(f),b.preventDefault()})})}(window.jQuery),!function(a){"use strict";var b=function(b,c){this.$element=a(b),this.options=a.extend({},a.fn.collapse.defaults,c),this.options.parent&&(this.$parent=a(this.options.parent)),this.options.toggle&&this.toggle()};b.prototype={constructor:b,dimension:function(){var a=this.$element.hasClass("width");return a?"width":"height"},show:function(){var b=this.dimension(),c=a.camelCase(["scroll",b].join("-")),d=this.$parent&&this.$parent.find(".in"),e;d&&d.length&&(e=d.data("collapse"),d.collapse("hide"),e||d.data("collapse",null)),this.$element[b](0),this.transition("addClass","show","shown"),this.$element[b](this.$element[0][c])},hide:function(){var a=this.dimension();this.reset(this.$element[a]()),this.transition("removeClass","hide","hidden"),this.$element[a](0)},reset:function(a){var b=this.dimension();return this.$element.removeClass("collapse")[b](a||"auto")[0].offsetWidth,this.$element[a?"addClass":"removeClass"]("collapse"),this},transition:function(b,c,d){var e=this,f=function(){c=="show"&&e.reset(),e.$element.trigger(d)};this.$element.trigger(c)[b]("in"),a.support.transition&&this.$element.hasClass("collapse")?this.$element.one(a.support.transition.end,f):f()},toggle:function(){this[this.$element.hasClass("in")?"hide":"show"]()}},a.fn.collapse=function(c){return this.each(function(){var d=a(this),e=d.data("collapse"),f=typeof c=="object"&&c;e||d.data("collapse",e=new b(this,f)),typeof c=="string"&&e[c]()})},a.fn.collapse.defaults={toggle:!0},a.fn.collapse.Constructor=b,a(function(){a("body").on("click.collapse.data-api","[data-toggle=collapse]",function(b){var c=a(this),d,e=c.attr("data-target")||b.preventDefault()||(d=c.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""),f=a(e).data("collapse")?"toggle":c.data();a(e).collapse(f)})})}(window.jQuery),!function(a){function d(){a(b).parent().removeClass("open")}"use strict";var b='[data-toggle="dropdown"]',c=function(b){var c=a(b).on("click.dropdown.data-api",this.toggle);a("html").on("click.dropdown.data-api",function(){c.parent().removeClass("open")})};c.prototype={constructor:c,toggle:function(b){var c=a(this),e=c.attr("data-target"),f,g;return e||(e=c.attr("href"),e=e&&e.replace(/.*(?=#[^\s]*$)/,"")),f=a(e),f.length||(f=c.parent()),g=f.hasClass("open"),d(),!g&&f.toggleClass("open"),!1}},a.fn.dropdown=function(b){return this.each(function(){var d=a(this),e=d.data("dropdown");e||d.data("dropdown",e=new c(this)),typeof b=="string"&&e[b].call(d)})},a.fn.dropdown.Constructor=c,a(function(){a("html").on("click.dropdown.data-api",d),a("body").on("click.dropdown.data-api",b,c.prototype.toggle)})}(window.jQuery),!function(a){function c(){var b=this,c=setTimeout(function(){b.$element.off(a.support.transition.end),d.call(b)},500);this.$element.one(a.support.transition.end,function(){clearTimeout(c),d.call(b)})}function d(a){this.$element.hide().trigger("hidden"),e.call(this)}function e(b){var c=this,d=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var e=a.support.transition&&d;this.$backdrop=a('

    ').modal({backdrop:false}).draggable({handle:".modal-header"});var modalContent="
    ×

    "+modals[i].title+"

    ";modalContent+="
    "+modals[i].content+"
    ";modalContent+=footerTemplate(i,modals);$('#'+modalId).html(modalContent);modalArray[i].modal("hide");$(modals[i].target).ready(function(){var direction,bounce;if(modals[i].placement=="top right"){bounce="up right";direction="down right"}else if(modals[i].placement=="top left"){bounce="up left";direction="down left"}else if(modals[i].placement=="top"){bounce="up";direction="down"}else if(modals[i].placement=="bottom right"){bounce="down right";direction="up right"}else if(modals[i].placement=="bottom left"){bounce="down left";direction="up left"}else{bounce="down";direction="right"} +$(modals[i].target).popoverext({title:"",content:"arrow",footer:"",placement:modals[i].placement,id:true,fixed:true,trigger:'manual',template:'
    ',onShow:function(){$('.pointer').css('top','0px');$(".popover .pointer").effect("custombounce",{times:1000,direction:bounce,distance:50,gravity:false},2000,function(){});},leftOffset:modals[i].leftOffset?modals[i].leftOffset:0,topOffset:modals[i].topOffset?modals[i].topOffset:0,hideOnBlur:true});});$(modals[i].target+"Popover").empty().html("arrow");} +$(window).resize(function(){centerModal();});function centerModal(){$(tourIdSel).css("left",$(window).width()/2-$(tourIdSel).width()/2);$(tourIdSel).css("margin-top",-$(tourIdSel).height()/2);} +function nextModal(i){if(modals.length-1!=i){$(modals[i].target).popoverext('hide');$(modals[i+1].target).popoverext('show');modalArray[i].modal('hide');modalArray[i+1].modal('show');}else{$(modals[i].target).popoverext('hide');modalArray[i].modal('hide');tourModal.modal("show");centerModal();}} +function prevModal(i){$(modals[i].target).popoverext('hide');$(modals[i-1].target).popoverext('show');modalArray[i].modal('hide');modalArray[i-1].modal('show');} +function skipTour(i){$(modals[i].target).popoverext('hide');modalArray[i].modal('hide');tourModal.modal("show");centerModal();} +function footerTemplate(i,modals){var content=$('
    ') +var footer=$("
    ");var skip=$(""+SUGAR.language.get('app_strings','LBL_TOUR_SKIP')+"");var next=$(''+SUGAR.language.get('app_strings','LBL_TOUR_NEXT')+' ');content.append(footer);footer.append(skip).append(next);var back=$(''+SUGAR.language.get('app_strings','LBL_TOUR_BACK')+'');$('#nextModal'+i).live("click",function(){nextModal(i);});$('#prevModal'+i).live("click",function(){prevModal(i);});$('#skipTour').live("click",function(){skipTour(i);});if(i!=0){footer.append(back);} +return content.html();}}});},saveUserPref:function(url){$.ajax({type:"GET",url:url});}};}(); \ No newline at end of file diff --git a/include/language/en_us.lang.php b/include/language/en_us.lang.php index 0a2abba3..15ef098e 100644 --- a/include/language/en_us.lang.php +++ b/include/language/en_us.lang.php @@ -1123,6 +1123,11 @@ $app_list_strings = array ( ); $app_strings = array ( + 'LBL_TOUR_NEXT' => 'Next', + 'LBL_TOUR_SKIP' => 'Skip', + 'LBL_TOUR_BACK' => 'Back', + 'LBL_TOUR_CLOSE' => 'Close', + 'LBL_TOUR_TAKE_TOUR' => 'Take the tour', 'LBL_MY_AREA_LINKS' => 'My area links: ' /*for 508 compliance fix*/, 'LBL_GETTINGAIR' => 'Getting Air' /*for 508 compliance fix*/, 'LBL_WELCOMEBAR' => 'Welcome' /*for 508 compliance fix*/, @@ -3265,4 +3270,12 @@ $app_list_strings ['emailTemplates_type_list_no_workflow'] = array ( 'campaign' => 'Campaign' , 'email' => 'Email', ); +$app_strings ['documentation'] = array ( + 'LBL_DOCS' => 'Documentation', + 'ULT' => '02_Sugar_Ultimate', + 'ENT' => '02_Sugar_Enterprise', + 'CORP' => '03_Sugar_Corporate', + 'PRO' => '04_Sugar_Professional', + 'COM' => '05_Sugar_Community_Edition' +); ?> diff --git a/include/phpmailer/license.txt b/include/phpmailer/LICENSE similarity index 100% rename from include/phpmailer/license.txt rename to include/phpmailer/LICENSE diff --git a/include/phpmailer/README b/include/phpmailer/README index 16dd4a01..f66012d4 100644 --- a/include/phpmailer/README +++ b/include/phpmailer/README @@ -1,14 +1,46 @@ /******************************************************************* -* The http://phpmailer.codeworxtech.com/ website now carries a few * -* advertisements through the Google Adsense network. Please visit * -* the advertiser sites and help us offset some of our costs. * -* Thanks .... * +* http://code.google.com/a/apache-extras.org/p/phpmailer/ * ********************************************************************/ PHPMailer Full Featured Email Transfer Class for PHP ========================================== +Version 5.2.1 (January 16, 2012) + +Patch release (see changelog.txt). + +Version 5.2.0 (July 19, 2011) + +With the release of this version, PHPMailer has moved to Apache +Extras: + http://code.google.com/a/apache-extras.org/p/phpmailer/ + +Version 5.0.0 (April 02, 2009) + +With the release of this version, we are initiating a new version numbering +system to differentiate from the PHP4 version of PHPMailer. + +Most notable in this release is fully object oriented code. + +We now have available the PHPDocumentor (phpdocs) documentation. This is +separate from the regular download to keep file sizes down. Please see the +download area of http://phpmailer.codeworxtech.com. + +We also have created a new test script (see /test_script) that you can use +right out of the box. Copy the /test_script folder directly to your server (in +the same structure ... with class.phpmailer.php and class.smtp.php in the +folder above it. Then launch the test script with: +http://www.yourdomain.com/phpmailer/test_script/index.php +from this one script, you can test your server settings for mail(), sendmail (or +qmail), and SMTP. This will email you a sample email (using contents.html for +the email body) and two attachments. One of the attachments is used as an inline +image to demonstrate how PHPMailer will automatically detect if attachments are +the same source as inline graphics and only include one version. Once you click +the Submit button, the results will be displayed including any SMTP debug +information and send status. We will also display a version of the script that +you can cut and paste to include in your projects. Enjoy! + Version 2.3 (November 08, 2008) We have removed the /phpdoc from the downloads. All documentation is now on @@ -59,7 +91,7 @@ A quick note on E_STRICT: $myVar = date_default_timezone_get(); as a test, it will throw an error. -We have also included more example files to show the use of "mail()", +We have also included more example files to show the use of "sendmail", "mail()", "smtp", and "gmail". We are also looking for more programmers to join the volunteer development team. @@ -119,7 +151,7 @@ easy to use classes: AspEmail(tm) and AspMail. Both of these programs are COM components only available on Windows. They are also a little pricey for smaller projects. -Since I do Linux development I’ve missed these tools for my PHP coding. +Since I do Linux development I�ve missed these tools for my PHP coding. So I built a version myself that implements the same methods (object calls) that the Windows-based components do. It is open source and the LGPL license allows you to place the class in your proprietary PHP diff --git a/include/phpmailer/class.phpmailer.php b/include/phpmailer/class.phpmailer.php index a5be5b28..f3d05381 100644 --- a/include/phpmailer/class.phpmailer.php +++ b/include/phpmailer/class.phpmailer.php @@ -1,94 +1,17 @@ - 2011-03-03 18:00:00 -0700 (Thu, 03 Mar 2011) - eddy - bug 31778 - added html chars (apostrophe and ampersand) back to email address before sending - -r58121 - 2010-09-09 11:35:17 -0700 (Thu, 09 Sep 2010) - kjing - Merge: 717e037 0ca4d1c -Author: Jenny Gonsalves - Merge branch 'master' of git+ssh://github.com/sugarcrm/Mango - -r57158 - 2010-06-27 20:13:23 -0700 (Sun, 27 Jun 2010) - kjing - commit a2a7548e2a06c075c99a17472c9c5672e1ec1926 -Author: John Mertic - Bug 8312 - Set the encoding type to 'base64' by default if we are sending an HTML email - -r56990 - 2010-06-16 13:05:36 -0700 (Wed, 16 Jun 2010) - kjing - snapshot "Mango" svn branch to a new one for GitHub sync - -r56989 - 2010-06-16 13:01:33 -0700 (Wed, 16 Jun 2010) - kjing - defunt "Mango" svn dev branch before github cutover - -r55980 - 2010-04-19 13:31:28 -0700 (Mon, 19 Apr 2010) - kjing - create Mango (6.1) based on windex - -r55695 - 2010-03-30 17:46:05 -0700 (Tue, 30 Mar 2010) - mitani - #36026 -Fixes an issue where CCed recipents would not be listed in the email. Need to upgrade PHP Mailer later on to the latest - -r51719 - 2009-10-22 10:18:00 -0700 (Thu, 22 Oct 2009) - mitani - Converted to Build 3 tags and updated the build system - -r51634 - 2009-10-19 13:32:22 -0700 (Mon, 19 Oct 2009) - mitani - Windex is the branch for Sugar Sales 1.0 development - -r51443 - 2009-10-12 13:34:36 -0700 (Mon, 12 Oct 2009) - jmertic - Bug 33332 - Made application PHP 5.3 compliant with E_DEPRECATED warnings on by: -- Changing all ereg function to either preg or simple string based ones -- No more references to magic quotes. -- Change all the session_unregister() functions to just unset() the correct session variable instead. - -r51251 - 2009-09-30 09:30:59 -0700 (Wed, 30 Sep 2009) - roger - svn merge from Tokyo rev: 50982 - 51248. - -r50983 - 2009-09-21 13:45:37 -0700 (Mon, 21 Sep 2009) - ajay - Merged code from branches/tokyo version 50739 thru 50982 - -r50519 - 2009-08-31 15:20:00 -0700 (Mon, 31 Aug 2009) - sgandhi - 31348 - -r50375 - 2009-08-24 18:07:43 -0700 (Mon, 24 Aug 2009) - dwong - branch kobe2 from tokyo r50372 - -r50023 - 2009-08-07 16:30:05 -0700 (Fri, 07 Aug 2009) - eddy - Bug 32412 -Split logic in file to allow string to be parsed for template conversion -include/phpmailer/class.phpmailer.php - -r43691 - 2009-01-29 15:25:53 -0800 (Thu, 29 Jan 2009) - faissah - 27521 : Update to phpmailer version 2.3. - -r42807 - 2008-12-29 11:16:59 -0800 (Mon, 29 Dec 2008) - dwong - Branch from trunk/sugarcrm r42806 to branches/tokyo/sugarcrm - -r39785 - 2008-09-12 15:49:45 -0700 (Fri, 12 Sep 2008) - faissah - Update to PHPmailer 2.2.1 - -r39146 - 2008-08-26 17:16:04 -0700 (Tue, 26 Aug 2008) - awu - Merging pre_5_1_0 to trunk - -r23880 - 2007-06-26 15:14:35 -0700 (Tue, 26 Jun 2007) - julian - Fix for bug #13475: security vulnerability in phpmailer - -r11652 - 2006-02-21 18:24:06 -0800 (Tue, 21 Feb 2006) - chris - Bug 4719: updating PHPMailer classes for security (DDoS) -Touched: -include/phpmailer (everything) -include/SugarPHPMailer.php (adding our constructor) -modules/Email/Email.php (to use the new constructor) - -r10887 - 2006-01-05 22:51:15 -0800 (Thu, 05 Jan 2006) - chris - Bug 3979: fixed filename generation issues that caused PDFs to be sent with the wrong encoding type - -r10886 - 2006-01-05 18:24:55 -0800 (Thu, 05 Jan 2006) - chris - Bug 3979: initial code checkin to get reports scheduling in Scheduler - -r6053 - 2005-07-06 01:04:42 -0700 (Wed, 06 Jul 2005) - clint - Bug #1400 -Even if I have "Clint Oram " in the to field, I only end up seeing "clint@sugarcrm.com" in the received email. - -r5104 - 2005-05-04 15:33:41 -0700 (Wed, 04 May 2005) - majed - gets rid of HTTP_GET_VARS and what not which has been deprecated - -r1573 - 2004-10-29 17:23:17 -0700 (Fri, 29 Oct 2004) - julian - Fix: path to phpmailer language file wrong - -r915 - 2004-10-08 15:31:10 -0700 (Fri, 08 Oct 2004) - julian - E-mail notification feature + new admin console - - -*/ - - /*~ class.phpmailer.php .---------------------------------------------------------------------------. | Software: PHPMailer - PHP email class | -| Version: 2.3 | -| Contact: via sourceforge.net support pages (also www.codeworxtech.com) | -| Info: http://phpmailer.sourceforge.net | -| Support: http://sourceforge.net/projects/phpmailer/ | +| Version: 5.2.1 | +| Site: https://code.google.com/a/apache-extras.org/p/phpmailer/ | | ------------------------------------------------------------------------- | -| Author: Andy Prevost (project admininistrator) | -| Author: Brent R. Matzelle (original founder) | -| Copyright (c) 2004-2007, Andy Prevost. All Rights Reserved. | +| Admin: Jim Jagielski (project admininistrator) | +| Authors: Andy Prevost (codeworxtech) codeworxtech@users.sourceforge.net | +| : Marcus Bointon (coolbru) coolbru@users.sourceforge.net | +| : Jim Jagielski (jimjag) jimjag@gmail.com | +| Founder: Brent R. Matzelle (original founder) | +| Copyright (c) 2010-2012, Jim Jagielski. All Rights Reserved. | +| Copyright (c) 2004-2009, Andy Prevost. All Rights Reserved. | | Copyright (c) 2001-2003, Brent R. Matzelle | | ------------------------------------------------------------------------- | | License: Distributed under the Lesser General Public License (LGPL) | @@ -96,20 +19,23 @@ r915 - 2004-10-08 15:31:10 -0700 (Fri, 08 Oct 2004) - julian - E-mail notificati | This program is distributed in the hope that it will be useful - WITHOUT | | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | | FITNESS FOR A PARTICULAR PURPOSE. | -| ------------------------------------------------------------------------- | -| We offer a number of paid services (www.codeworxtech.com): | -| - Web Hosting on highly optimized fast and secure servers | -| - Technology Consulting | -| - Oursourcing (highly qualified programmers and graphic designers) | '---------------------------------------------------------------------------' +*/ /** * PHPMailer - PHP email transport class - * NOTE: Designed for use with PHP version 5 and up + * NOTE: Requires PHP version 5 or later * @package PHPMailer * @author Andy Prevost - * @copyright 2004 - 2008 Andy Prevost -*/ + * @author Marcus Bointon + * @author Jim Jagielski + * @copyright 2010 - 2012 Jim Jagielski + * @copyright 2004 - 2009 Andy Prevost + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +if (version_compare(PHP_VERSION, '5.0.0', '<') ) exit("Sorry, this version of PHPMailer will only run on PHP version 5 or greater!\n"); class PHPMailer { @@ -136,8 +62,8 @@ class PHPMailer { public $ContentType = 'text/plain'; /** - * Sets the Encoding of the message. Options for this are "8bit", - * "7bit", "binary", "base64", and "quoted-printable". + * Sets the Encoding of the message. Options for this are + * "8bit", "7bit", "binary", "base64", and "quoted-printable". * @var string */ public $Encoding = '8bit'; @@ -189,6 +115,27 @@ class PHPMailer { */ public $AltBody = ''; + /** + * Stores the complete compiled MIME message body. + * @var string + * @access protected + */ + protected $MIMEBody = ''; + + /** + * Stores the complete compiled MIME message headers. + * @var string + * @access protected + */ + protected $MIMEHeader = ''; + + /** + * Stores the complete sent MIME message (Body and Headers) + * @var string + * @access protected + */ + protected $SentMIMEMessage = ''; + /** * Sets word wrapping on the body of the message to a given number of * characters. @@ -208,19 +155,12 @@ class PHPMailer { */ public $Sendmail = '/usr/sbin/sendmail'; - /** - * Path to PHPMailer plugins. This is now only useful if the SMTP class + * Path to PHPMailer plugins. Useful if the SMTP class * is in a different directory than the PHP include path. * @var string */ - public $PluginDir = 'include/phpmailer/'; - - /** - * Holds PHPMailer version. - * @var string - */ - public $Version = "2.3"; + public $PluginDir = ''; /** * Sets the email address that a reading confirmation will be sent. @@ -241,7 +181,7 @@ class PHPMailer { * If empty, a unique id will be generated. * @var string */ - public $MessageID = ''; + public $MessageID = ''; ///////////////////////////////////////////////// // PROPERTIES FOR SMTP @@ -255,57 +195,57 @@ class PHPMailer { * Hosts will be tried in order. * @var string */ - public $Host = 'localhost'; + public $Host = 'localhost'; /** * Sets the default SMTP server port. * @var int */ - public $Port = 25; + public $Port = 25; /** * Sets the SMTP HELO of the message (Default is $Hostname). * @var string */ - public $Helo = ''; + public $Helo = ''; /** * Sets connection prefix. * Options are "", "ssl" or "tls" * @var string */ - public $SMTPSecure = ""; + public $SMTPSecure = ''; /** * Sets SMTP authentication. Utilizes the Username and Password variables. * @var bool */ - public $SMTPAuth = false; + public $SMTPAuth = false; /** * Sets SMTP username. * @var string */ - public $Username = ''; + public $Username = ''; /** * Sets SMTP password. * @var string */ - public $Password = ''; + public $Password = ''; /** - * Sets the SMTP server timeout in seconds. This function will not - * work with the win32 version. + * Sets the SMTP server timeout in seconds. + * This function will not work with the win32 version. * @var int */ - public $Timeout = 10; + public $Timeout = 10; /** * Sets SMTP class debugging on or off. * @var bool */ - public $SMTPDebug = false; + public $SMTPDebug = false; /** * Prevents the SMTP connection from being closed after each mail @@ -320,49 +260,129 @@ class PHPMailer { * emails, instead of sending to entire TO addresses * @var bool */ - public $SingleTo = false; + public $SingleTo = false; - /** + /** + * If SingleTo is true, this provides the array to hold the email addresses + * @var bool + */ + public $SingleToArray = array(); + + /** * Provides the ability to change the line ending * @var string */ - public $LE = "\r\n"; + public $LE = "\n"; + + /** + * Used with DKIM DNS Resource Record + * @var string + */ + public $DKIM_selector = 'phpmailer'; + + /** + * Used with DKIM DNS Resource Record + * optional, in format of email address 'you@yourdomain.com' + * @var string + */ + public $DKIM_identity = ''; + + /** + * Used with DKIM DNS Resource Record + * @var string + */ + public $DKIM_passphrase = ''; + + /** + * Used with DKIM DNS Resource Record + * optional, in format of email address 'you@yourdomain.com' + * @var string + */ + public $DKIM_domain = ''; + + /** + * Used with DKIM DNS Resource Record + * optional, in format of email address 'you@yourdomain.com' + * @var string + */ + public $DKIM_private = ''; + + /** + * Callback Action function name + * the function that handles the result of the send email action. Parameters: + * bool $result result of the send action + * string $to email address of the recipient + * string $cc cc email addresses + * string $bcc bcc email addresses + * string $subject the subject + * string $body the email body + * @var string + */ + public $action_function = ''; //'callbackAction'; + + /** + * Sets the PHPMailer Version number + * @var string + */ + public $Version = '5.2.1'; + + /** + * What to use in the X-Mailer header + * @var string + */ + public $XMailer = ''; ///////////////////////////////////////////////// - // PROPERTIES, PRIVATE + // PROPERTIES, PRIVATE AND PROTECTED ///////////////////////////////////////////////// - public $smtp = NULL; - private $to = array(); - private $cc = array(); - private $bcc = array(); - private $ReplyTo = array(); - public $attachment = array(); - private $CustomHeader = array(); - private $message_type = ''; - public $boundary = array(); - private $language = array(); - private $error_count = 0; - private $sign_cert_file = ""; - private $sign_key_file = ""; - private $sign_key_pass = ""; + protected $smtp = NULL; + protected $to = array(); + protected $cc = array(); + protected $bcc = array(); + protected $ReplyTo = array(); + protected $all_recipients = array(); + protected $attachment = array(); + protected $CustomHeader = array(); + protected $message_type = ''; + protected $boundary = array(); + protected $language = array(); + protected $error_count = 0; + protected $sign_cert_file = ''; + protected $sign_key_file = ''; + protected $sign_key_pass = ''; + protected $exceptions = false; + + ///////////////////////////////////////////////// + // CONSTANTS + ///////////////////////////////////////////////// + + const STOP_MESSAGE = 0; // message only, continue processing + const STOP_CONTINUE = 1; // message?, likely ok to continue processing + const STOP_CRITICAL = 2; // message, plus full stop, critical error reached ///////////////////////////////////////////////// // METHODS, VARIABLES ///////////////////////////////////////////////// + /** + * Constructor + * @param boolean $exceptions Should we throw external exceptions? + */ + public function __construct($exceptions = false) { + $this->exceptions = ($exceptions == true); + } + /** * Sets message type to HTML. - * @param bool $bool + * @param bool $ishtml * @return void */ - public function IsHTML($bool) { - if($bool == true) { + public function IsHTML($ishtml = true) { + if ($ishtml) { $this->ContentType = 'text/html'; - $this->Encoding = 'base64'; } else { $this->ContentType = 'text/plain'; - $this->Encoding = 'quoted-printable'; } } @@ -387,6 +407,9 @@ class PHPMailer { * @return void */ public function IsSendmail() { + if (!stristr(ini_get('sendmail_path'), 'sendmail')) { + $this->Sendmail = '/var/qmail/bin/sendmail'; + } $this->Mailer = 'sendmail'; } @@ -395,8 +418,10 @@ class PHPMailer { * @return void */ public function IsQmail() { - $this->Sendmail = '/var/qmail/bin/sendmail'; - $this->Mailer = 'sendmail'; + if (stristr(ini_get('sendmail_path'), 'qmail')) { + $this->Sendmail = '/var/qmail/bin/sendmail'; + } + $this->Mailer = 'sendmail'; } ///////////////////////////////////////////////// @@ -407,52 +432,144 @@ class PHPMailer { * Adds a "To" address. * @param string $address * @param string $name - * @return void + * @return boolean true on success, false if address already used */ public function AddAddress($address, $name = '') { - $cur = count($this->to); - $this->to[$cur][0] = trim($address); - $this->to[$cur][1] = $name; + return $this->AddAnAddress('to', $address, $name); } /** - * Adds a "Cc" address. Note: this function works - * with the SMTP mailer on win32, not with the "mail" - * mailer. + * Adds a "Cc" address. + * Note: this function works with the SMTP mailer on win32, not with the "mail" mailer. * @param string $address * @param string $name - * @return void + * @return boolean true on success, false if address already used */ public function AddCC($address, $name = '') { - $cur = count($this->cc); - $this->cc[$cur][0] = trim($address); - $this->cc[$cur][1] = $name; + return $this->AddAnAddress('cc', $address, $name); } /** - * Adds a "Bcc" address. Note: this function works - * with the SMTP mailer on win32, not with the "mail" - * mailer. + * Adds a "Bcc" address. + * Note: this function works with the SMTP mailer on win32, not with the "mail" mailer. * @param string $address * @param string $name - * @return void + * @return boolean true on success, false if address already used */ public function AddBCC($address, $name = '') { - $cur = count($this->bcc); - $this->bcc[$cur][0] = trim($address); - $this->bcc[$cur][1] = $name; + return $this->AddAnAddress('bcc', $address, $name); } /** * Adds a "Reply-to" address. * @param string $address * @param string $name - * @return void + * @return boolean */ public function AddReplyTo($address, $name = '') { - $cur = count($this->ReplyTo); - $this->ReplyTo[$cur][0] = trim($address); - $this->ReplyTo[$cur][1] = $name; + return $this->AddAnAddress('Reply-To', $address, $name); + } + + /** + * Adds an address to one of the recipient arrays + * Addresses that have been added already return false, but do not throw exceptions + * @param string $kind One of 'to', 'cc', 'bcc', 'ReplyTo' + * @param string $address The email address to send to + * @param string $name + * @return boolean true on success, false if address already used or invalid in some way + * @access protected + */ + protected function AddAnAddress($kind, $address, $name = '') { + if (!preg_match('/^(to|cc|bcc|Reply-To)$/', $kind)) { + $this->SetError($this->Lang('Invalid recipient array').': '.$kind); + if ($this->exceptions) { + throw new phpmailerException('Invalid recipient array: ' . $kind); + } + if ($this->SMTPDebug) { + echo $this->Lang('Invalid recipient array').': '.$kind; + } + return false; + } + $address = trim($address); + $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim + if (!self::ValidateAddress($address)) { + $this->SetError($this->Lang('invalid_address').': '. $address); + if ($this->exceptions) { + throw new phpmailerException($this->Lang('invalid_address').': '.$address); + } + if ($this->SMTPDebug) { + echo $this->Lang('invalid_address').': '.$address; + } + return false; + } + if ($kind != 'Reply-To') { + if (!isset($this->all_recipients[strtolower($address)])) { + array_push($this->$kind, array($address, $name)); + $this->all_recipients[strtolower($address)] = true; + return true; + } + } else { + if (!array_key_exists(strtolower($address), $this->ReplyTo)) { + $this->ReplyTo[strtolower($address)] = array($address, $name); + return true; + } + } + return false; +} + +/** + * Set the From and FromName properties + * @param string $address + * @param string $name + * @return boolean + */ + public function SetFrom($address, $name = '', $auto = 1) { + $address = trim($address); + $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim + if (!self::ValidateAddress($address)) { + $this->SetError($this->Lang('invalid_address').': '. $address); + if ($this->exceptions) { + throw new phpmailerException($this->Lang('invalid_address').': '.$address); + } + if ($this->SMTPDebug) { + echo $this->Lang('invalid_address').': '.$address; + } + return false; + } + $this->From = $address; + $this->FromName = $name; + if ($auto) { + if (empty($this->ReplyTo)) { + $this->AddAnAddress('Reply-To', $address, $name); + } + if (empty($this->Sender)) { + $this->Sender = $address; + } + } + return true; + } + + /** + * Check that a string looks roughly like an email address should + * Static so it can be used without instantiation + * Tries to use PHP built-in validator in the filter extension (from PHP 5.2), falls back to a reasonably competent regex validator + * Conforms approximately to RFC2822 + * @link http://www.hexillion.com/samples/#Regex Original pattern found here + * @param string $address The email address to check + * @return boolean + * @static + * @access public + */ + public static function ValidateAddress($address) { + if (function_exists('filter_var')) { //Introduced in PHP 5.2 + if(filter_var($address, FILTER_VALIDATE_EMAIL) === FALSE) { + return false; + } else { + return true; + } + } else { + return preg_match('/^(?:[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+\.)*[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+@(?:(?:(?:[a-zA-Z0-9_](?:[a-zA-Z0-9_\-](?!\.)){0,61}[a-zA-Z0-9_-]?\.)+[a-zA-Z0-9_](?:[a-zA-Z0-9_\-](?!$)){0,61}[a-zA-Z0-9_]?)|(?:\[(?:(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\.){3}(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\]))$/', $address); + } } ///////////////////////////////////////////////// @@ -466,273 +583,342 @@ class PHPMailer { * @return bool */ public function Send() { - $header = ''; - $body = ''; - $result = true; - - if((count($this->to) + count($this->cc) + count($this->bcc)) < 1) { - $this->SetError($this->Lang('provide_address')); + try { + if(!$this->PreSend()) return false; + return $this->PostSend(); + } catch (phpmailerException $e) { + $this->SentMIMEMessage = ''; + $this->SetError($e->getMessage()); + if ($this->exceptions) { + throw $e; + } return false; } + } - //iterate through recipients and add back in html characters (apostrophe ' and ampersand &) to email addresses - //this was causing email bounces in names like "O'Reilly@example.com" being sent over as "O'Reilly@example.com" - foreach($this->to as $k=>$addr){ - $this->to[$k][0] = htmlspecialchars_decode($addr[0],ENT_QUOTES); - } - foreach($this->cc as $k=>$addr){ - $this->cc[$k][0] = htmlspecialchars_decode($addr[0],ENT_QUOTES); - } - foreach($this->bcc as $k=>$addr){ - $this->bcc[$k][0] = htmlspecialchars_decode($addr[0],ENT_QUOTES); - } + protected function PreSend() { + try { + $mailHeader = ""; + if ((count($this->to) + count($this->cc) + count($this->bcc)) < 1) { + throw new phpmailerException($this->Lang('provide_address'), self::STOP_CRITICAL); + } - /* Set whether the message is multipart/alternative */ - if(!empty($this->AltBody)) { - $this->ContentType = 'multipart/alternative'; - } + // Set whether the message is multipart/alternative + if(!empty($this->AltBody)) { + $this->ContentType = 'multipart/alternative'; + } + + $this->error_count = 0; // reset errors + $this->SetMessageType(); + //Refuse to send an empty message + if (empty($this->Body)) { + throw new phpmailerException($this->Lang('empty_message'), self::STOP_CRITICAL); + } + + $this->MIMEHeader = $this->CreateHeader(); + $this->MIMEBody = $this->CreateBody(); + + // To capture the complete message when using mail(), create + // an extra header list which CreateHeader() doesn't fold in + if ($this->Mailer == 'mail') { + if (count($this->to) > 0) { + $mailHeader .= $this->AddrAppend("To", $this->to); + } else { + $mailHeader .= $this->HeaderLine("To", "undisclosed-recipients:;"); + } + $mailHeader .= $this->HeaderLine('Subject', $this->EncodeHeader($this->SecureHeader(trim($this->Subject)))); + // if(count($this->cc) > 0) { + // $mailHeader .= $this->AddrAppend("Cc", $this->cc); + // } + } + + // digitally sign with DKIM if enabled + if ($this->DKIM_domain && $this->DKIM_private) { + $header_dkim = $this->DKIM_Add($this->MIMEHeader, $this->EncodeHeader($this->SecureHeader($this->Subject)), $this->MIMEBody); + $this->MIMEHeader = str_replace("\r\n", "\n", $header_dkim) . $this->MIMEHeader; + } - $this->error_count = 0; // reset errors - $this->SetMessageType(); - $header .= $this->CreateHeader(); - $body = $this->CreateBody(); + $this->SentMIMEMessage = sprintf("%s%s\r\n\r\n%s",$this->MIMEHeader,$mailHeader,$this->MIMEBody); + return true; - if($body == '') { + } catch (phpmailerException $e) { + $this->SetError($e->getMessage()); + if ($this->exceptions) { + throw $e; + } return false; } + } - /* Choose the mailer */ - switch($this->Mailer) { - case 'sendmail': - $result = $this->SendmailSend($header, $body); - break; - case 'smtp': - $result = $this->SmtpSend($header, $body); - break; - case 'mail': - $result = $this->MailSend($header, $body); - break; - default: - $result = $this->MailSend($header, $body); - break; - //$this->SetError($this->Mailer . $this->Lang('mailer_not_supported')); - //$result = false; - //break; - } + protected function PostSend() { + try { + // Choose the mailer and send through it + switch($this->Mailer) { + case 'sendmail': + return $this->SendmailSend($this->MIMEHeader, $this->MIMEBody); + case 'smtp': + return $this->SmtpSend($this->MIMEHeader, $this->MIMEBody); + case 'mail': + return $this->MailSend($this->MIMEHeader, $this->MIMEBody); + default: + return $this->MailSend($this->MIMEHeader, $this->MIMEBody); + } - return $result; + } catch (phpmailerException $e) { + $this->SetError($e->getMessage()); + if ($this->exceptions) { + throw $e; + } + if ($this->SMTPDebug) { + echo $e->getMessage()."\n"; + } + return false; + } } /** * Sends mail using the $Sendmail program. - * @access public + * @param string $header The message headers + * @param string $body The message body + * @access protected * @return bool */ - public function SendmailSend($header, $body) { + protected function SendmailSend($header, $body) { if ($this->Sender != '') { $sendmail = sprintf("%s -oi -f %s -t", escapeshellcmd($this->Sendmail), escapeshellarg($this->Sender)); } else { $sendmail = sprintf("%s -oi -t", escapeshellcmd($this->Sendmail)); } - - if(!@$mail = popen($sendmail, 'w')) { - $this->SetError($this->Lang('execute') . $this->Sendmail); - return false; - } - - fputs($mail, $header); - fputs($mail, $body); - - $result = pclose($mail); - if (version_compare(phpversion(), '4.2.3') == -1) { - $result = $result >> 8 & 0xFF; - } - if($result != 0) { - $this->SetError($this->Lang('execute') . $this->Sendmail); - return false; + if ($this->SingleTo === true) { + foreach ($this->SingleToArray as $key => $val) { + if(!@$mail = popen($sendmail, 'w')) { + throw new phpmailerException($this->Lang('execute') . $this->Sendmail, self::STOP_CRITICAL); + } + fputs($mail, "To: " . $val . "\n"); + fputs($mail, $header); + fputs($mail, $body); + $result = pclose($mail); + // implement call back function if it exists + $isSent = ($result == 0) ? 1 : 0; + $this->doCallback($isSent, $val, $this->cc, $this->bcc, $this->Subject, $body); + if($result != 0) { + throw new phpmailerException($this->Lang('execute') . $this->Sendmail, self::STOP_CRITICAL); + } + } + } else { + if(!@$mail = popen($sendmail, 'w')) { + throw new phpmailerException($this->Lang('execute') . $this->Sendmail, self::STOP_CRITICAL); + } + fputs($mail, $header); + fputs($mail, $body); + $result = pclose($mail); + // implement call back function if it exists + $isSent = ($result == 0) ? 1 : 0; + $this->doCallback($isSent, $this->to, $this->cc, $this->bcc, $this->Subject, $body); + if($result != 0) { + throw new phpmailerException($this->Lang('execute') . $this->Sendmail, self::STOP_CRITICAL); + } } - return true; } /** * Sends mail using the PHP mail() function. - * @access public + * @param string $header The message headers + * @param string $body The message body + * @access protected * @return bool */ - public function MailSend($header, $body) { - - $to = ''; - for($i = 0; $i < count($this->to); $i++) { - if($i != 0) { $to .= ', '; } - $to .= $this->AddrFormat($this->to[$i]); + protected function MailSend($header, $body) { + $toArr = array(); + foreach($this->to as $t) { + $toArr[] = $this->AddrFormat($t); } + $to = implode(', ', $toArr); - $toArr = explode(',', $to); - - $params = sprintf("-oi -f %s", $this->Sender); - if ($this->Sender != '' && strlen(ini_get('safe_mode'))< 1) { + if (empty($this->Sender)) { + $params = "-oi "; + } else { + $params = sprintf("-oi -f %s", $this->Sender); + } + if ($this->Sender != '' and !ini_get('safe_mode')) { $old_from = ini_get('sendmail_from'); ini_set('sendmail_from', $this->Sender); if ($this->SingleTo === true && count($toArr) > 1) { foreach ($toArr as $key => $val) { $rt = @mail($val, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params); + // implement call back function if it exists + $isSent = ($rt == 1) ? 1 : 0; + $this->doCallback($isSent, $val, $this->cc, $this->bcc, $this->Subject, $body); } } else { $rt = @mail($to, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params); + // implement call back function if it exists + $isSent = ($rt == 1) ? 1 : 0; + $this->doCallback($isSent, $to, $this->cc, $this->bcc, $this->Subject, $body); } } else { if ($this->SingleTo === true && count($toArr) > 1) { foreach ($toArr as $key => $val) { $rt = @mail($val, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params); + // implement call back function if it exists + $isSent = ($rt == 1) ? 1 : 0; + $this->doCallback($isSent, $val, $this->cc, $this->bcc, $this->Subject, $body); } } else { - $rt = @mail($to, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header); + $rt = @mail($to, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params); + // implement call back function if it exists + $isSent = ($rt == 1) ? 1 : 0; + $this->doCallback($isSent, $to, $this->cc, $this->bcc, $this->Subject, $body); } } - if (isset($old_from)) { ini_set('sendmail_from', $old_from); } - if(!$rt) { - $this->SetError($this->Lang('instantiate')); - return false; + throw new phpmailerException($this->Lang('instantiate'), self::STOP_CRITICAL); } - return true; } /** - * Sends mail via SMTP using PhpSMTP (Author: - * Chris Ryan). Returns bool. Returns false if there is a - * bad MAIL FROM, RCPT, or DATA input. - * @access public + * Sends mail via SMTP using PhpSMTP + * Returns false if there is a bad MAIL FROM, RCPT, or DATA input. + * @param string $header The message headers + * @param string $body The message body + * @uses SMTP + * @access protected * @return bool */ - public function SmtpSend($header, $body) { - include_once($this->PluginDir . 'class.smtp.php'); - $error = ''; + protected function SmtpSend($header, $body) { + require_once $this->PluginDir . 'class.smtp.php'; $bad_rcpt = array(); if(!$this->SmtpConnect()) { - return false; + throw new phpmailerException($this->Lang('smtp_connect_failed'), self::STOP_CRITICAL); } - $smtp_from = ($this->Sender == '') ? $this->From : $this->Sender; if(!$this->smtp->Mail($smtp_from)) { - $error = $this->Lang('from_failed') . $smtp_from; - $this->SetError($error); - $this->smtp->Reset(); - return false; + throw new phpmailerException($this->Lang('from_failed') . $smtp_from, self::STOP_CRITICAL); } - /* Attempt to send attach all recipients */ - for($i = 0; $i < count($this->to); $i++) { - if(!$this->smtp->Recipient($this->to[$i][0])) { - $bad_rcpt[] = $this->to[$i][0]; + // Attempt to send attach all recipients + foreach($this->to as $to) { + if (!$this->smtp->Recipient($to[0])) { + $bad_rcpt[] = $to[0]; + // implement call back function if it exists + $isSent = 0; + $this->doCallback($isSent, $to[0], '', '', $this->Subject, $body); + } else { + // implement call back function if it exists + $isSent = 1; + $this->doCallback($isSent, $to[0], '', '', $this->Subject, $body); } } - for($i = 0; $i < count($this->cc); $i++) { - if(!$this->smtp->Recipient($this->cc[$i][0])) { - $bad_rcpt[] = $this->cc[$i][0]; + foreach($this->cc as $cc) { + if (!$this->smtp->Recipient($cc[0])) { + $bad_rcpt[] = $cc[0]; + // implement call back function if it exists + $isSent = 0; + $this->doCallback($isSent, '', $cc[0], '', $this->Subject, $body); + } else { + // implement call back function if it exists + $isSent = 1; + $this->doCallback($isSent, '', $cc[0], '', $this->Subject, $body); } } - for($i = 0; $i < count($this->bcc); $i++) { - if(!$this->smtp->Recipient($this->bcc[$i][0])) { - $bad_rcpt[] = $this->bcc[$i][0]; + foreach($this->bcc as $bcc) { + if (!$this->smtp->Recipient($bcc[0])) { + $bad_rcpt[] = $bcc[0]; + // implement call back function if it exists + $isSent = 0; + $this->doCallback($isSent, '', '', $bcc[0], $this->Subject, $body); + } else { + // implement call back function if it exists + $isSent = 1; + $this->doCallback($isSent, '', '', $bcc[0], $this->Subject, $body); } } - if(count($bad_rcpt) > 0) { // Create error message - for($i = 0; $i < count($bad_rcpt); $i++) { - if($i != 0) { - $error .= ', '; - } - $error .= $bad_rcpt[$i]; - } - $error = $this->Lang('recipients_failed') . $error; - $this->SetError($error); - $this->smtp->Reset(); - return false; - } + if (count($bad_rcpt) > 0 ) { //Create error message for any bad addresses + $badaddresses = implode(', ', $bad_rcpt); + throw new phpmailerException($this->Lang('recipients_failed') . $badaddresses); + } if(!$this->smtp->Data($header . $body)) { - $this->SetError($this->Lang('data_not_accepted')); - $this->smtp->Reset(); - return false; + throw new phpmailerException($this->Lang('data_not_accepted'), self::STOP_CRITICAL); } if($this->SMTPKeepAlive == true) { $this->smtp->Reset(); - } else { - $this->SmtpClose(); } - return true; } /** - * Initiates a connection to an SMTP server. Returns false if the - * operation failed. + * Initiates a connection to an SMTP server. + * Returns false if the operation failed. + * @uses SMTP * @access public * @return bool */ public function SmtpConnect() { - if($this->smtp == NULL) { + if(is_null($this->smtp)) { $this->smtp = new SMTP(); } $this->smtp->do_debug = $this->SMTPDebug; $hosts = explode(';', $this->Host); $index = 0; - $connection = ($this->smtp->Connected()); - - /* Retry while there is no connection */ - while($index < count($hosts) && $connection == false) { - $hostinfo = array(); - if(preg_match('/^(.+):([0-9]+)$/i', $hosts[$index], $hostinfo)) { - $host = $hostinfo[1]; - $port = $hostinfo[2]; - } else { - $host = $hosts[$index]; - $port = $this->Port; - } + $connection = $this->smtp->Connected(); + + // Retry while there is no connection + try { + while($index < count($hosts) && !$connection) { + $hostinfo = array(); + if (preg_match('/^(.+):([0-9]+)$/', $hosts[$index], $hostinfo)) { + $host = $hostinfo[1]; + $port = $hostinfo[2]; + } else { + $host = $hosts[$index]; + $port = $this->Port; + } - $tls = ($this->SMTPSecure == 'tls'); - $ssl = ($this->SMTPSecure == 'ssl'); + $tls = ($this->SMTPSecure == 'tls'); + $ssl = ($this->SMTPSecure == 'ssl'); - if($this->smtp->Connect(($ssl ? 'ssl://':'').$host, $port, $this->Timeout)) { + if ($this->smtp->Connect(($ssl ? 'ssl://':'').$host, $port, $this->Timeout)) { - $hello = ($this->Helo != '' ? $this->Helo : $this->ServerHostname()); - $this->smtp->Hello($hello); + $hello = ($this->Helo != '' ? $this->Helo : $this->ServerHostname()); + $this->smtp->Hello($hello); - if($tls) { - if(!$this->smtp->StartTLS()) { - $this->SetError($this->Lang("tls")); - $this->smtp->Reset(); - $connection = false; - } + if ($tls) { + if (!$this->smtp->StartTLS()) { + throw new phpmailerException($this->Lang('tls')); + } - //We must resend HELLO after tls negociation - $this->smtp->Hello($hello); - } + //We must resend HELO after tls negotiation + $this->smtp->Hello($hello); + } - $connection = true; - if($this->SMTPAuth) { - if(!$this->smtp->Authenticate($this->Username, $this->Password)) { - $this->SetError($this->Lang('authenticate')); - $this->smtp->Reset(); - $connection = false; + $connection = true; + if ($this->SMTPAuth) { + if (!$this->smtp->Authenticate($this->Username, $this->Password)) { + throw new phpmailerException($this->Lang('authenticate')); + } } } + $index++; + if (!$connection) { + throw new phpmailerException($this->Lang('connect_host')); + } + } + } catch (phpmailerException $e) { + $this->smtp->Reset(); + if ($this->exceptions) { + throw $e; } - $index++; - } - if(!$connection) { - $this->SetError($this->Lang('connect_host')); } - - return $connection; + return true; } /** @@ -740,7 +926,7 @@ class PHPMailer { * @return void */ public function SmtpClose() { - if($this->smtp != NULL) { + if(!is_null($this->smtp)) { if($this->smtp->Connected()) { $this->smtp->Quit(); $this->smtp->Close(); @@ -749,36 +935,48 @@ class PHPMailer { } /** - * Sets the language for all class error messages. Returns false - * if it cannot load the language file. The default language type - * is English. - * @param string $lang_type Type of language (e.g. Portuguese: "br") - * @param string $lang_path Path to the language file directory - * @access public - * @return bool - */ - function SetLanguage($lang_type = 'en', $lang_path = 'language/') { - $filename = $lang_path.'phpmailer.lang-'.$lang_type.'.php'; - if (file_exists($filename)) { - include($filename); - } else { - $PHPMAILER_LANG = array(); - $PHPMAILER_LANG["provide_address"] = 'You must provide at least one ' . - $PHPMAILER_LANG["mailer_not_supported"] = ' mailer is not supported.'; - $PHPMAILER_LANG["execute"] = 'Could not execute: '; - $PHPMAILER_LANG["instantiate"] = 'Could not instantiate mail function.'; - $PHPMAILER_LANG["authenticate"] = 'SMTP Error: Could not authenticate.'; - $PHPMAILER_LANG["from_failed"] = 'The following From address failed: '; - $PHPMAILER_LANG["recipients_failed"] = 'SMTP Error: The following ' . - $PHPMAILER_LANG["data_not_accepted"] = 'SMTP Error: Data not accepted.'; - $PHPMAILER_LANG["connect_host"] = 'SMTP Error: Could not connect to SMTP host.'; - $PHPMAILER_LANG["file_access"] = 'Could not access file: '; - $PHPMAILER_LANG["file_open"] = 'File Error: Could not open file: '; - $PHPMAILER_LANG["encoding"] = 'Unknown encoding: '; - $PHPMAILER_LANG["signing"] = 'Signing Error: '; + * Sets the language for all class error messages. + * Returns false if it cannot load the language file. The default language is English. + * @param string $langcode ISO 639-1 2-character language code (e.g. Portuguese: "br") + * @param string $lang_path Path to the language file directory + * @access public + */ + function SetLanguage($langcode = 'en', $lang_path = 'language/') { + //Define full set of translatable strings + $PHPMAILER_LANG = array( + 'provide_address' => 'You must provide at least one recipient email address.', + 'mailer_not_supported' => ' mailer is not supported.', + 'execute' => 'Could not execute: ', + 'instantiate' => 'Could not instantiate mail function.', + 'authenticate' => 'SMTP Error: Could not authenticate.', + 'from_failed' => 'The following From address failed: ', + 'recipients_failed' => 'SMTP Error: The following recipients failed: ', + 'data_not_accepted' => 'SMTP Error: Data not accepted.', + 'connect_host' => 'SMTP Error: Could not connect to SMTP host.', + 'file_access' => 'Could not access file: ', + 'file_open' => 'File Error: Could not open file: ', + 'encoding' => 'Unknown encoding: ', + 'signing' => 'Signing Error: ', + 'smtp_error' => 'SMTP server error: ', + 'empty_message' => 'Message body empty', + 'invalid_address' => 'Invalid address', + 'variable_set' => 'Cannot set or reset variable: ' + ); + //Overwrite language-specific strings. This way we'll never have missing translations - no more "language string failed to load"! + $l = true; + if ($langcode != 'en') { //There is no English translation file + $l = @include $lang_path.'phpmailer.lang-'.$langcode.'.php'; } $this->language = $PHPMAILER_LANG; - return true; + return ($l == true); //Returns false if language not found + } + + /** + * Return the current array of language strings + * @return array + */ + public function GetTranslations() { + return $this->language; } ///////////////////////////////////////////////// @@ -792,12 +990,11 @@ class PHPMailer { */ public function AddrAppend($type, $addr) { $addr_str = $type . ': '; - $addr_str .= $this->AddrFormat($addr[0]); - if(count($addr) > 1) { - for($i = 1; $i < count($addr); $i++) { - $addr_str .= ', ' . $this->AddrFormat($addr[$i]); - } + $addresses = array(); + foreach ($addr as $a) { + $addresses[] = $this->AddrFormat($a); } + $addr_str .= implode(', ', $addresses); $addr_str .= $this->LE; return $addr_str; @@ -809,19 +1006,20 @@ class PHPMailer { * @return string */ public function AddrFormat($addr) { - if(empty($addr[1])) { - $formatted = $this->SecureHeader($addr[0]); + if (empty($addr[1])) { + return $this->SecureHeader($addr[0]); } else { - $formatted = $this->EncodeHeader($this->SecureHeader($addr[1]), 'phrase') . " <" . $this->SecureHeader($addr[0]) . ">"; + return $this->EncodeHeader($this->SecureHeader($addr[1]), 'phrase') . " <" . $this->SecureHeader($addr[0]) . ">"; } - - return $formatted; } /** * Wraps message for use with mailers that do not * automatically perform wrapping and for quoted-printable. * Original written by philippe. + * @param string $message The message to wrap + * @param integer $length The line length to wrap to + * @param boolean $qp_mode Whether to run in Quoted-Printable mode * @access public * @return string */ @@ -838,7 +1036,7 @@ class PHPMailer { $line = explode($this->LE, $message); $message = ''; - for ($i=0 ;$i < count($line); $i++) { + for ($i = 0 ;$i < count($line); $i++) { $line_part = explode(' ', $line[$i]); $buf = ''; for ($e = 0; $emessage_type) { case 'alt': - /* fall through */ - case 'alt_attachments': + case 'alt_inline': + case 'alt_attach': + case 'alt_inline_attach': $this->AltBody = $this->WrapText($this->AltBody, $this->WordWrap); break; default: @@ -965,63 +1164,74 @@ class PHPMailer { /** * Assembles message header. * @access public - * @return string + * @return string The assembled header */ public function CreateHeader() { $result = ''; - /* Set the boundaries */ + // Set the boundaries $uniq_id = md5(uniqid(time())); $this->boundary[1] = 'b1_' . $uniq_id; $this->boundary[2] = 'b2_' . $uniq_id; + $this->boundary[3] = 'b3_' . $uniq_id; - $result .= $this->HeaderLine('Date', $this->RFCDate()); + $result .= $this->HeaderLine('Date', self::RFCDate()); if($this->Sender == '') { $result .= $this->HeaderLine('Return-Path', trim($this->From)); } else { $result .= $this->HeaderLine('Return-Path', trim($this->Sender)); } - /* To be created automatically by mail() */ + // To be created automatically by mail() if($this->Mailer != 'mail') { - if(count($this->to) > 0) { - $result .= $this->AddrAppend('To', $this->to); - } elseif (count($this->cc) == 0) { - $result .= $this->HeaderLine('To', 'undisclosed-recipients:;'); + if ($this->SingleTo === true) { + foreach($this->to as $t) { + $this->SingleToArray[] = $this->AddrFormat($t); + } + } else { + if(count($this->to) > 0) { + $result .= $this->AddrAppend('To', $this->to); + } elseif (count($this->cc) == 0) { + $result .= $this->HeaderLine('To', 'undisclosed-recipients:;'); + } } - } + } $from = array(); $from[0][0] = trim($this->From); $from[0][1] = $this->FromName; $result .= $this->AddrAppend('From', $from); - /* sendmail and mail() extract Cc from the header before sending */ - if(count($this->cc) > 0) { + // sendmail and mail() extract Cc from the header before sending + if(count($this->cc) > 0) { $result .= $this->AddrAppend('Cc', $this->cc); } - /* sendmail and mail() extract Bcc from the header before sending */ + // sendmail and mail() extract Bcc from the header before sending if((($this->Mailer == 'sendmail') || ($this->Mailer == 'mail')) && (count($this->bcc) > 0)) { $result .= $this->AddrAppend('Bcc', $this->bcc); } if(count($this->ReplyTo) > 0) { - $result .= $this->AddrAppend('Reply-to', $this->ReplyTo); + $result .= $this->AddrAppend('Reply-To', $this->ReplyTo); } - /* mail() sets the subject itself */ + // mail() sets the subject itself if($this->Mailer != 'mail') { $result .= $this->HeaderLine('Subject', $this->EncodeHeader($this->SecureHeader($this->Subject))); } if($this->MessageID != '') { - $result .= $this->HeaderLine('Message-ID',$this->MessageID); + $result .= $this->HeaderLine('Message-ID', $this->MessageID); } else { $result .= sprintf("Message-ID: <%s@%s>%s", $uniq_id, $this->ServerHostname(), $this->LE); } $result .= $this->HeaderLine('X-Priority', $this->Priority); - $result .= $this->HeaderLine('X-Mailer', 'PHPMailer (phpmailer.codeworxtech.com) [version ' . $this->Version . ']'); + if($this->XMailer) { + $result .= $this->HeaderLine('X-Mailer', $this->XMailer); + } else { + $result .= $this->HeaderLine('X-Mailer', 'PHPMailer '.$this->Version.' (http://code.google.com/a/apache-extras.org/p/phpmailer/)'); + } if($this->ConfirmReadingTo != '') { $result .= $this->HeaderLine('Disposition-Notification-To', '<' . trim($this->ConfirmReadingTo) . '>'); @@ -1049,19 +1259,21 @@ class PHPMailer { switch($this->message_type) { case 'plain': $result .= $this->HeaderLine('Content-Transfer-Encoding', $this->Encoding); - $result .= sprintf("Content-Type: %s; charset=\"%s\"", $this->ContentType, $this->CharSet); + $result .= $this->TextLine('Content-Type: '.$this->ContentType.'; charset="'.$this->CharSet.'"'); break; - case 'attachments': - /* fall through */ - case 'alt_attachments': - if($this->InlineImageExists()){ - $result .= sprintf("Content-Type: %s;%s\ttype=\"text/html\";%s\tboundary=\"%s\"%s", 'multipart/related', $this->LE, $this->LE, $this->boundary[1], $this->LE); - } else { - $result .= $this->HeaderLine('Content-Type', 'multipart/mixed;'); - $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"'); - } + case 'inline': + $result .= $this->HeaderLine('Content-Type', 'multipart/related;'); + $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"'); + break; + case 'attach': + case 'inline_attach': + case 'alt_attach': + case 'alt_inline_attach': + $result .= $this->HeaderLine('Content-Type', 'multipart/mixed;'); + $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"'); break; case 'alt': + case 'alt_inline': $result .= $this->HeaderLine('Content-Type', 'multipart/alternative;'); $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"'); break; @@ -1075,85 +1287,152 @@ class PHPMailer { } /** - * Assembles the message body. Returns an empty string on failure. + * Returns the MIME message (headers and body). Only really valid post PreSend(). * @access public * @return string */ + public function GetSentMIMEMessage() { + return $this->SentMIMEMessage; + } + + + /** + * Assembles the message body. Returns an empty string on failure. + * @access public + * @return string The assembled message body + */ public function CreateBody() { - $result = ''; + $body = ''; if ($this->sign_key_file) { - $result .= $this->GetMailMIME(); + $body .= $this->GetMailMIME(); } $this->SetWordWrap(); switch($this->message_type) { + case 'plain': + $body .= $this->EncodeString($this->Body, $this->Encoding); + break; + case 'inline': + $body .= $this->GetBoundary($this->boundary[1], '', '', ''); + $body .= $this->EncodeString($this->Body, $this->Encoding); + $body .= $this->LE.$this->LE; + $body .= $this->AttachAll("inline", $this->boundary[1]); + break; + case 'attach': + $body .= $this->GetBoundary($this->boundary[1], '', '', ''); + $body .= $this->EncodeString($this->Body, $this->Encoding); + $body .= $this->LE.$this->LE; + $body .= $this->AttachAll("attachment", $this->boundary[1]); + break; + case 'inline_attach': + $body .= $this->TextLine("--" . $this->boundary[1]); + $body .= $this->HeaderLine('Content-Type', 'multipart/related;'); + $body .= $this->TextLine("\tboundary=\"" . $this->boundary[2] . '"'); + $body .= $this->LE; + $body .= $this->GetBoundary($this->boundary[2], '', '', ''); + $body .= $this->EncodeString($this->Body, $this->Encoding); + $body .= $this->LE.$this->LE; + $body .= $this->AttachAll("inline", $this->boundary[2]); + $body .= $this->LE; + $body .= $this->AttachAll("attachment", $this->boundary[1]); + break; case 'alt': - $result .= $this->GetBoundary($this->boundary[1], '', 'text/plain', ''); - $result .= $this->EncodeString($this->AltBody, $this->Encoding); - $result .= $this->LE.$this->LE; - $result .= $this->GetBoundary($this->boundary[1], '', 'text/html', ''); - $result .= $this->EncodeString($this->Body, $this->Encoding); - $result .= $this->LE.$this->LE; - $result .= $this->EndBoundary($this->boundary[1]); + $body .= $this->GetBoundary($this->boundary[1], '', 'text/plain', ''); + $body .= $this->EncodeString($this->AltBody, $this->Encoding); + $body .= $this->LE.$this->LE; + $body .= $this->GetBoundary($this->boundary[1], '', 'text/html', ''); + $body .= $this->EncodeString($this->Body, $this->Encoding); + $body .= $this->LE.$this->LE; + $body .= $this->EndBoundary($this->boundary[1]); break; - case 'plain': - $result .= $this->EncodeString($this->Body, $this->Encoding); + case 'alt_inline': + $body .= $this->GetBoundary($this->boundary[1], '', 'text/plain', ''); + $body .= $this->EncodeString($this->AltBody, $this->Encoding); + $body .= $this->LE.$this->LE; + $body .= $this->TextLine("--" . $this->boundary[1]); + $body .= $this->HeaderLine('Content-Type', 'multipart/related;'); + $body .= $this->TextLine("\tboundary=\"" . $this->boundary[2] . '"'); + $body .= $this->LE; + $body .= $this->GetBoundary($this->boundary[2], '', 'text/html', ''); + $body .= $this->EncodeString($this->Body, $this->Encoding); + $body .= $this->LE.$this->LE; + $body .= $this->AttachAll("inline", $this->boundary[2]); + $body .= $this->LE; + $body .= $this->EndBoundary($this->boundary[1]); break; - case 'attachments': - $result .= $this->GetBoundary($this->boundary[1], '', '', ''); - $result .= $this->EncodeString($this->Body, $this->Encoding); - $result .= $this->LE; - $result .= $this->AttachAll(); + case 'alt_attach': + $body .= $this->TextLine("--" . $this->boundary[1]); + $body .= $this->HeaderLine('Content-Type', 'multipart/alternative;'); + $body .= $this->TextLine("\tboundary=\"" . $this->boundary[2] . '"'); + $body .= $this->LE; + $body .= $this->GetBoundary($this->boundary[2], '', 'text/plain', ''); + $body .= $this->EncodeString($this->AltBody, $this->Encoding); + $body .= $this->LE.$this->LE; + $body .= $this->GetBoundary($this->boundary[2], '', 'text/html', ''); + $body .= $this->EncodeString($this->Body, $this->Encoding); + $body .= $this->LE.$this->LE; + $body .= $this->EndBoundary($this->boundary[2]); + $body .= $this->LE; + $body .= $this->AttachAll("attachment", $this->boundary[1]); break; - case 'alt_attachments': - $result .= sprintf("--%s%s", $this->boundary[1], $this->LE); - $result .= sprintf("Content-Type: %s;%s" . "\tboundary=\"%s\"%s", 'multipart/alternative', $this->LE, $this->boundary[2], $this->LE.$this->LE); - $result .= $this->GetBoundary($this->boundary[2], '', 'text/plain', '') . $this->LE; // Create text body - $result .= $this->EncodeString($this->AltBody, $this->Encoding); - $result .= $this->LE.$this->LE; - $result .= $this->GetBoundary($this->boundary[2], '', 'text/html', '') . $this->LE; // Create the HTML body - $result .= $this->EncodeString($this->Body, $this->Encoding); - $result .= $this->LE.$this->LE; - $result .= $this->EndBoundary($this->boundary[2]); - $result .= $this->AttachAll(); + case 'alt_inline_attach': + $body .= $this->TextLine("--" . $this->boundary[1]); + $body .= $this->HeaderLine('Content-Type', 'multipart/alternative;'); + $body .= $this->TextLine("\tboundary=\"" . $this->boundary[2] . '"'); + $body .= $this->LE; + $body .= $this->GetBoundary($this->boundary[2], '', 'text/plain', ''); + $body .= $this->EncodeString($this->AltBody, $this->Encoding); + $body .= $this->LE.$this->LE; + $body .= $this->TextLine("--" . $this->boundary[2]); + $body .= $this->HeaderLine('Content-Type', 'multipart/related;'); + $body .= $this->TextLine("\tboundary=\"" . $this->boundary[3] . '"'); + $body .= $this->LE; + $body .= $this->GetBoundary($this->boundary[3], '', 'text/html', ''); + $body .= $this->EncodeString($this->Body, $this->Encoding); + $body .= $this->LE.$this->LE; + $body .= $this->AttachAll("inline", $this->boundary[3]); + $body .= $this->LE; + $body .= $this->EndBoundary($this->boundary[2]); + $body .= $this->LE; + $body .= $this->AttachAll("attachment", $this->boundary[1]); break; } - if($this->IsError()) { - $result = ''; - } else if ($this->sign_key_file) { - $file = tempnam("", "mail"); - $fp = fopen($file, "w"); - fwrite($fp, $result); - fclose($fp); - $signed = tempnam("", "signed"); - - if (@openssl_pkcs7_sign($file, $signed, "file://".$this->sign_cert_file, array("file://".$this->sign_key_file, $this->sign_key_pass), null)) { - $fp = fopen($signed, "r"); - $result = ''; - while(!feof($fp)){ - $result = $result . fread($fp, 1024); + if ($this->IsError()) { + $body = ''; + } elseif ($this->sign_key_file) { + try { + $file = tempnam('', 'mail'); + file_put_contents($file, $body); //TODO check this worked + $signed = tempnam("", "signed"); + if (@openssl_pkcs7_sign($file, $signed, "file://".$this->sign_cert_file, array("file://".$this->sign_key_file, $this->sign_key_pass), NULL)) { + @unlink($file); + $body = file_get_contents($signed); + @unlink($signed); + } else { + @unlink($file); + @unlink($signed); + throw new phpmailerException($this->Lang("signing").openssl_error_string()); + } + } catch (phpmailerException $e) { + $body = ''; + if ($this->exceptions) { + throw $e; } - fclose($fp); - } else { - $this->SetError($this->Lang("signing").openssl_error_string()); - $result = ''; } - - unlink($file); - unlink($signed); } - return $result; + return $body; } /** * Returns the start of a message boundary. - * @access public + * @access protected + * @return string */ - public function GetBoundary($boundary, $charSet, $contentType, $encoding) { + protected function GetBoundary($boundary, $charSet, $contentType, $encoding) { $result = ''; if($charSet == '') { $charSet = $this->CharSet; @@ -1165,7 +1444,7 @@ class PHPMailer { $encoding = $this->Encoding; } $result .= $this->TextLine('--' . $boundary); - $result .= sprintf("Content-Type: %s; charset = \"%s\"", $contentType, $charSet); + $result .= sprintf("Content-Type: %s; charset=\"%s\"", $contentType, $charSet); $result .= $this->LE; $result .= $this->HeaderLine('Content-Transfer-Encoding', $encoding); $result .= $this->LE; @@ -1175,34 +1454,29 @@ class PHPMailer { /** * Returns the end of a message boundary. - * @access public + * @access protected + * @return string */ - public function EndBoundary($boundary) { + protected function EndBoundary($boundary) { return $this->LE . '--' . $boundary . '--' . $this->LE; } /** * Sets the message type. - * @access public + * @access protected * @return void */ - public function SetMessageType() { - if(count($this->attachment) < 1 && strlen($this->AltBody) < 1) { - $this->message_type = 'plain'; - } else { - if(count($this->attachment) > 0) { - $this->message_type = 'attachments'; - } - if(strlen($this->AltBody) > 0 && count($this->attachment) < 1) { - $this->message_type = 'alt'; - } - if(strlen($this->AltBody) > 0 && count($this->attachment) > 0) { - $this->message_type = 'alt_attachments'; - } - } + protected function SetMessageType() { + $this->message_type = array(); + if($this->AlternativeExists()) $this->message_type[] = "alt"; + if($this->InlineImageExists()) $this->message_type[] = "inline"; + if($this->AttachmentExists()) $this->message_type[] = "attach"; + $this->message_type = implode("_", $this->message_type); + if($this->message_type == "") $this->message_type = "plain"; } - /* Returns a formatted header line. + /** + * Returns a formatted header line. * @access public * @return string */ @@ -1234,123 +1508,169 @@ class PHPMailer { * @return bool */ public function AddAttachment($path, $name = '', $encoding = 'base64', $type = 'application/octet-stream') { - if(!@is_file($path)) { - $this->SetError($this->Lang('file_access') . $path); - return false; - } + try { + if ( !@is_file($path) ) { + throw new phpmailerException($this->Lang('file_access') . $path, self::STOP_CONTINUE); + } + $filename = basename($path); + if ( $name == '' ) { + $name = $filename; + } - $filename = basename($path); - if($name == '') { - $name = $filename; + $this->attachment[] = array( + 0 => $path, + 1 => $filename, + 2 => $name, + 3 => $encoding, + 4 => $type, + 5 => false, // isStringAttachment + 6 => 'attachment', + 7 => 0 + ); + + } catch (phpmailerException $e) { + $this->SetError($e->getMessage()); + if ($this->exceptions) { + throw $e; + } + if ($this->SMTPDebug) { + echo $e->getMessage()."\n"; + } + if ( $e->getCode() == self::STOP_CRITICAL ) { + return false; + } } - - $cur = count($this->attachment); - $this->attachment[$cur][0] = $path; - $this->attachment[$cur][1] = $filename; - $this->attachment[$cur][2] = $name; - $this->attachment[$cur][3] = $encoding; - $this->attachment[$cur][4] = $type; - $this->attachment[$cur][5] = false; // isStringAttachment - $this->attachment[$cur][6] = 'attachment'; - $this->attachment[$cur][7] = 0; - return true; } + /** + * Return the current array of attachments + * @return array + */ + public function GetAttachments() { + return $this->attachment; + } + /** * Attaches all fs, string, and binary attachments to the message. * Returns an empty string on failure. - * @access public + * @access protected * @return string */ - public function AttachAll() { - /* Return text of body */ + protected function AttachAll($disposition_type, $boundary) { + // Return text of body $mime = array(); + $cidUniq = array(); + $incl = array(); + + // Add all attachments + foreach ($this->attachment as $attachment) { + // CHECK IF IT IS A VALID DISPOSITION_FILTER + if($attachment[6] == $disposition_type) { + // Check for string attachment + $bString = $attachment[5]; + if ($bString) { + $string = $attachment[0]; + } else { + $path = $attachment[0]; + } - /* Add all attachments */ - for($i = 0; $i < count($this->attachment); $i++) { - /* Check for string attachment */ - $bString = $this->attachment[$i][5]; - if ($bString) { - $string = $this->attachment[$i][0]; - } else { - $path = $this->attachment[$i][0]; - } - - $filename = $this->attachment[$i][1]; - $name = $this->attachment[$i][2]; - $encoding = $this->attachment[$i][3]; - $type = $this->attachment[$i][4]; - $disposition = $this->attachment[$i][6]; - $cid = $this->attachment[$i][7]; - - $mime[] = sprintf("--%s%s", $this->boundary[1], $this->LE); - //$mime[] = sprintf("Content-Type: %s; name=\"%s\"%s", $type, $name, $this->LE); - $mime[] = sprintf("Content-Type: %s; name=\"%s\"%s", $type, $this->EncodeHeader($this->SecureHeader($name)), $this->LE); - $mime[] = sprintf("Content-Transfer-Encoding: %s%s", $encoding, $this->LE); - - if($disposition == 'inline') { - $mime[] = sprintf("Content-ID: <%s>%s", $cid, $this->LE); - } + $inclhash = md5(serialize($attachment)); + if (in_array($inclhash, $incl)) { continue; } + $incl[] = $inclhash; + $filename = $attachment[1]; + $name = $attachment[2]; + $encoding = $attachment[3]; + $type = $attachment[4]; + $disposition = $attachment[6]; + $cid = $attachment[7]; + if ( $disposition == 'inline' && isset($cidUniq[$cid]) ) { continue; } + $cidUniq[$cid] = true; + + $mime[] = sprintf("--%s%s", $boundary, $this->LE); + $mime[] = sprintf("Content-Type: %s; name=\"%s\"%s", $type, $this->EncodeHeader($this->SecureHeader($name)), $this->LE); + $mime[] = sprintf("Content-Transfer-Encoding: %s%s", $encoding, $this->LE); + + if($disposition == 'inline') { + $mime[] = sprintf("Content-ID: <%s>%s", $cid, $this->LE); + } - //$mime[] = sprintf("Content-Disposition: %s; filename=\"%s\"%s", $disposition, $name, $this->LE.$this->LE); - $mime[] = sprintf("Content-Disposition: %s; filename=\"%s\"%s", $disposition, $this->EncodeHeader($this->SecureHeader($name)), $this->LE.$this->LE); + $mime[] = sprintf("Content-Disposition: %s; filename=\"%s\"%s", $disposition, $this->EncodeHeader($this->SecureHeader($name)), $this->LE.$this->LE); - /* Encode as string attachment */ - if($bString) { - $mime[] = $this->EncodeString($string, $encoding); - if($this->IsError()) { - return ''; - } - $mime[] = $this->LE.$this->LE; - } else { - $mime[] = $this->EncodeFile($path, $encoding); - if($this->IsError()) { - return ''; + // Encode as string attachment + if($bString) { + $mime[] = $this->EncodeString($string, $encoding); + if($this->IsError()) { + return ''; + } + $mime[] = $this->LE.$this->LE; + } else { + $mime[] = $this->EncodeFile($path, $encoding); + if($this->IsError()) { + return ''; + } + $mime[] = $this->LE.$this->LE; } - $mime[] = $this->LE.$this->LE; } } - $mime[] = sprintf("--%s--%s", $this->boundary[1], $this->LE); + $mime[] = sprintf("--%s--%s", $boundary, $this->LE); - return join('', $mime); + return implode("", $mime); } /** - * Encodes attachment in requested format. Returns an - * empty string on failure. - * @access public + * Encodes attachment in requested format. + * Returns an empty string on failure. + * @param string $path The full path to the file + * @param string $encoding The encoding to use; one of 'base64', '7bit', '8bit', 'binary', 'quoted-printable' + * @see EncodeFile() + * @access protected * @return string */ - public function EncodeFile ($path, $encoding = 'base64') { - if(!@$fd = fopen($path, 'rb')) { - $this->SetError($this->Lang('file_open') . $path); - return ''; - } - if (function_exists('get_magic_quotes')) { + protected function EncodeFile($path, $encoding = 'base64') { + try { + if (!is_readable($path)) { + throw new phpmailerException($this->Lang('file_open') . $path, self::STOP_CONTINUE); + } + if (function_exists('get_magic_quotes')) { function get_magic_quotes() { - return false; + return false; } -} - if (version_compare(PHP_VERSION, '5.3.0', '<')) { - $magic_quotes = get_magic_quotes_runtime(); - set_magic_quotes_runtime(0); + } + $magic_quotes = get_magic_quotes_runtime(); + if ($magic_quotes) { + if (version_compare(PHP_VERSION, '5.3.0', '<')) { + set_magic_quotes_runtime(0); + } else { + ini_set('magic_quotes_runtime', 0); + } + } + $file_buffer = file_get_contents($path); + $file_buffer = $this->EncodeString($file_buffer, $encoding); + if ($magic_quotes) { + if (version_compare(PHP_VERSION, '5.3.0', '<')) { + set_magic_quotes_runtime($magic_quotes); + } else { + ini_set('magic_quotes_runtime', $magic_quotes); + } + } + return $file_buffer; + } catch (Exception $e) { + $this->SetError($e->getMessage()); + return ''; } - $file_buffer = file_get_contents($path); - $file_buffer = $this->EncodeString($file_buffer, $encoding); - fclose($fd); - if (version_compare(PHP_VERSION, '5.3.0', '<')) { set_magic_quotes_runtime($magic_quotes); } - return $file_buffer; } /** - * Encodes string to requested format. Returns an - * empty string on failure. + * Encodes string to requested format. + * Returns an empty string on failure. + * @param string $str The text to encode + * @param string $encoding The encoding to use; one of 'base64', '7bit', '8bit', 'binary', 'quoted-printable' * @access public * @return string */ - public function EncodeString ($str, $encoding = 'base64') { + public function EncodeString($str, $encoding = 'base64') { $encoded = ''; switch(strtolower($encoding)) { case 'base64': @@ -1359,6 +1679,7 @@ class PHPMailer { case '7bit': case '8bit': $encoded = $this->FixEOL($str); + //Make sure it ends with a line break if (substr($encoded, -(strlen($this->LE))) != $this->LE) $encoded .= $this->LE; break; @@ -1376,17 +1697,17 @@ class PHPMailer { } /** - * Encode a header string to best of Q, B, quoted or none. + * Encode a header string to best (shortest) of Q, B, quoted or none. * @access public * @return string */ - public function EncodeHeader ($str, $position = 'text') { + public function EncodeHeader($str, $position = 'text') { $x = 0; switch (strtolower($position)) { case 'phrase': if (!preg_match('/[\200-\377]/', $str)) { - /* Can't use addslashes as we don't know what value has magic_quotes_sybase. */ + // Can't use addslashes as we don't know what value has magic_quotes_sybase $encoded = addcslashes($str, "\0..\37\177\\\""); if (($str == $encoded) && !preg_match('/[^A-Za-z0-9!#$%&\'*+\/=?^_`{|}~ -]/', $str)) { return ($encoded); @@ -1398,7 +1719,7 @@ class PHPMailer { break; case 'comment': $x = preg_match_all('/[()"]/', $str, $matches); - /* Fall-through */ + // Fall-through case 'text': default: $x += preg_match_all('/[\000-\010\013\014\016-\037\177-\377]/', $str, $matches); @@ -1410,16 +1731,13 @@ class PHPMailer { } $maxlen = 75 - 7 - strlen($this->CharSet); - /* Try to select the encoding which should produce the shortest output */ + // Try to select the encoding which should produce the shortest output if (strlen($str)/3 < $x) { $encoding = 'B'; if (function_exists('mb_strlen') && $this->HasMultiBytes($str)) { - // Use a custom function which correctly encodes and wraps long - // multibyte strings without breaking lines within a character + // Use a custom function which correctly encodes and wraps long + // multibyte strings without breaking lines within a character $encoded = $this->Base64EncodeWrapMB($str); - // Bug 39171 - Need to change the passed back line-ending to \n, since that's what the - // regex below expects. - $encoded = str_replace($this->LE, "\n", trim($encoded)); } else { $encoded = base64_encode($str); $maxlen -= $maxlen % 4; @@ -1448,7 +1766,7 @@ class PHPMailer { if (function_exists('mb_strlen')) { return (strlen($str) > mb_strlen($str, $this->CharSet)); } else { // Assume no multibytes (we can't handle without mbstring functions anyway) - return False; + return false; } } @@ -1494,13 +1812,14 @@ class PHPMailer { /** * Encode string to quoted-printable. + * Only uses standard PHP, slow, but will always work * @access public * @param string $string the text to encode * @param integer $line_max Number of chars allowed on a line before wrapping * @return string */ - public function EncodeQP( $input = '', $line_max = 76, $space_conv = false ) { - $hex = array('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'); + public function EncodeQPphp( $input = '', $line_max = 76, $space_conv = false) { + $hex = array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'); $lines = preg_split('/(?:\r\n|\r|\n)/', $input); $eol = "\r\n"; $escape = '='; @@ -1540,14 +1859,50 @@ class PHPMailer { return $output; } + /** + * Encode string to RFC2045 (6.7) quoted-printable format + * Uses a PHP5 stream filter to do the encoding about 64x faster than the old version + * Also results in same content as you started with after decoding + * @see EncodeQPphp() + * @access public + * @param string $string the text to encode + * @param integer $line_max Number of chars allowed on a line before wrapping + * @param boolean $space_conv Dummy param for compatibility with existing EncodeQP function + * @return string + * @author Marcus Bointon + */ + public function EncodeQP($string, $line_max = 76, $space_conv = false) { + if (function_exists('quoted_printable_encode')) { //Use native function if it's available (>= PHP5.3) + return quoted_printable_encode($string); + } + $filters = stream_get_filters(); + if (!in_array('convert.*', $filters)) { //Got convert stream filter? + return $this->EncodeQPphp($string, $line_max, $space_conv); //Fall back to old implementation + } + $fp = fopen('php://temp/', 'r+'); + $string = preg_replace('/\r\n?/', $this->LE, $string); //Normalise line breaks + $params = array('line-length' => $line_max, 'line-break-chars' => $this->LE); + $s = stream_filter_append($fp, 'convert.quoted-printable-encode', STREAM_FILTER_READ, $params); + fputs($fp, $string); + rewind($fp); + $out = stream_get_contents($fp); + stream_filter_remove($s); + $out = preg_replace('/^\./m', '=2E', $out); //Encode . if it is first char on a line, workaround for bug in Exchange + fclose($fp); + return $out; + } + /** * Encode string to q encoding. + * @link http://tools.ietf.org/html/rfc2047 + * @param string $str the text to encode + * @param string $position Where the text is going to be used, see the RFC for what that means * @access public * @return string */ - public function EncodeQ ($str, $position = 'text') { - /* There should not be any EOL in the string */ - $encoded = preg_replace("[\r\n]", '', $str); + public function EncodeQ($str, $position = 'text') { + // There should not be any EOL in the string + $encoded = preg_replace('/[\r\n]*/', '', $str); switch (strtolower($position)) { case 'phrase': @@ -1557,13 +1912,14 @@ class PHPMailer { $encoded = preg_replace("/([\(\)\"])/e", "'='.sprintf('%02X', ord('\\1'))", $encoded); case 'text': default: - /* Replace every high ascii, control =, ? and _ characters */ + // Replace every high ascii, control =, ? and _ characters + //TODO using /e (equivalent to eval()) is probably not a good idea $encoded = preg_replace('/([\000-\011\013\014\016-\037\075\077\137\177-\377])/e', - "'='.sprintf('%02X', ord('\\1'))", $encoded); + "'='.sprintf('%02X', ord(stripslashes('\\1')))", $encoded); break; } - /* Replace every spaces to _ (more readable than =20) */ + // Replace every spaces to _ (more readable than =20) $encoded = str_replace(' ', '_', $encoded); return $encoded; @@ -1580,16 +1936,17 @@ class PHPMailer { * @return void */ public function AddStringAttachment($string, $filename, $encoding = 'base64', $type = 'application/octet-stream') { - /* Append to $attachment array */ - $cur = count($this->attachment); - $this->attachment[$cur][0] = $string; - $this->attachment[$cur][1] = $filename; - $this->attachment[$cur][2] = $filename; - $this->attachment[$cur][3] = $encoding; - $this->attachment[$cur][4] = $type; - $this->attachment[$cur][5] = true; // isString - $this->attachment[$cur][6] = 'attachment'; - $this->attachment[$cur][7] = 0; + // Append to $attachment array + $this->attachment[] = array( + 0 => $string, + 1 => $filename, + 2 => basename($filename), + 3 => $encoding, + 4 => $type, + 5 => true, // isStringAttachment + 6 => 'attachment', + 7 => 0 + ); } /** @@ -1607,45 +1964,70 @@ class PHPMailer { */ public function AddEmbeddedImage($path, $cid, $name = '', $encoding = 'base64', $type = 'application/octet-stream') { - if(!@is_file($path)) { + if ( !@is_file($path) ) { $this->SetError($this->Lang('file_access') . $path); return false; } $filename = basename($path); - if($name == '') { + if ( $name == '' ) { $name = $filename; } - /* Append to $attachment array */ - $cur = count($this->attachment); - $this->attachment[$cur][0] = $path; - $this->attachment[$cur][1] = $filename; - $this->attachment[$cur][2] = $name; - $this->attachment[$cur][3] = $encoding; - $this->attachment[$cur][4] = $type; - $this->attachment[$cur][5] = false; - $this->attachment[$cur][6] = 'inline'; - $this->attachment[$cur][7] = $cid; + // Append to $attachment array + $this->attachment[] = array( + 0 => $path, + 1 => $filename, + 2 => $name, + 3 => $encoding, + 4 => $type, + 5 => false, // isStringAttachment + 6 => 'inline', + 7 => $cid + ); return true; } + public function AddStringEmbeddedImage($string, $cid, $filename = '', $encoding = 'base64', $type = 'application/octet-stream') { + // Append to $attachment array + $this->attachment[] = array( + 0 => $string, + 1 => $filename, + 2 => basename($filename), + 3 => $encoding, + 4 => $type, + 5 => true, // isStringAttachment + 6 => 'inline', + 7 => $cid + ); + } + /** * Returns true if an inline attachment is present. * @access public * @return bool */ public function InlineImageExists() { - $result = false; - for($i = 0; $i < count($this->attachment); $i++) { - if($this->attachment[$i][6] == 'inline') { - $result = true; - break; + foreach($this->attachment as $attachment) { + if ($attachment[6] == 'inline') { + return true; } } + return false; + } - return $result; + public function AttachmentExists() { + foreach($this->attachment as $attachment) { + if ($attachment[6] == 'attachment') { + return true; + } + } + return false; + } + + public function AlternativeExists() { + return strlen($this->AltBody)>0; } ///////////////////////////////////////////////// @@ -1657,6 +2039,9 @@ class PHPMailer { * @return void */ public function ClearAddresses() { + foreach($this->to as $to) { + unset($this->all_recipients[strtolower($to[0])]); + } $this->to = array(); } @@ -1665,6 +2050,9 @@ class PHPMailer { * @return void */ public function ClearCCs() { + foreach($this->cc as $cc) { + unset($this->all_recipients[strtolower($cc[0])]); + } $this->cc = array(); } @@ -1673,6 +2061,9 @@ class PHPMailer { * @return void */ public function ClearBCCs() { + foreach($this->bcc as $bcc) { + unset($this->all_recipients[strtolower($bcc[0])]); + } $this->bcc = array(); } @@ -1693,6 +2084,7 @@ class PHPMailer { $this->to = array(); $this->cc = array(); $this->bcc = array(); + $this->all_recipients = array(); } /** @@ -1718,21 +2110,27 @@ class PHPMailer { /** * Adds the error message to the error container. - * Returns void. - * @access private + * @access protected * @return void */ - public function SetError($msg) { + protected function SetError($msg) { $this->error_count++; + if ($this->Mailer == 'smtp' and !is_null($this->smtp)) { + $lasterror = $this->smtp->getError(); + if (!empty($lasterror) and array_key_exists('smtp_msg', $lasterror)) { + $msg .= '

    ' . $this->Lang('smtp_error') . $lasterror['smtp_msg'] . "

    \n"; + } + } $this->ErrorInfo = $msg; } /** * Returns the proper RFC 822 formatted date. - * @access private + * @access public * @return string + * @static */ - private static function RFCDate() { + public static function RFCDate() { $tz = date('Z'); $tzs = ($tz < 0) ? '-' : '+'; $tz = abs($tz); @@ -1744,16 +2142,16 @@ class PHPMailer { /** * Returns the server hostname or 'localhost.localdomain' if unknown. - * @access private + * @access protected * @return string */ - public function ServerHostname() { + protected function ServerHostname() { if (!empty($this->Hostname)) { $result = $this->Hostname; } elseif (isset($_SERVER['SERVER_NAME'])) { $result = $_SERVER['SERVER_NAME']; } else { - $result = "localhost.localdomain"; + $result = 'localhost.localdomain'; } return $result; @@ -1761,10 +2159,10 @@ class PHPMailer { /** * Returns a message in the appropriate language. - * @access private + * @access protected * @return string */ - public function Lang($key) { + protected function Lang($key) { if(count($this->language) < 1) { $this->SetLanguage('en'); // set the default language } @@ -1787,10 +2185,10 @@ class PHPMailer { /** * Changes every end of line from CR or LF to CRLF. - * @access private + * @access public * @return string */ - private function FixEOL($str) { + public function FixEOL($str) { $str = str_replace("\r\n", "\n", $str); $str = str_replace("\r", "\n", $str); $str = str_replace("\n", $this->LE, $str); @@ -1811,44 +2209,48 @@ class PHPMailer { * @access public * @return $message */ - public function MsgHTML($message,$basedir='') { - preg_match_all("/(src|background)=\"(.*)\"/Ui", $message, $images); + public function MsgHTML($message, $basedir = '') { + preg_match_all("/(src|background)=[\"'](.*)[\"']/Ui", $message, $images); if(isset($images[2])) { foreach($images[2] as $i => $url) { // do not change urls for absolute images (thanks to corvuscorax) - if (!preg_match('/^[A-z][A-z]*:\/\//',$url)) { + if (!preg_match('#^[A-z]+://#', $url)) { $filename = basename($url); $directory = dirname($url); - ($directory == '.')?$directory='':''; + ($directory == '.') ? $directory='': ''; $cid = 'cid:' . md5($filename); - $fileParts = preg_split("\.", $filename); - $ext = $fileParts[1]; - $mimeType = $this->_mime_types($ext); - if ( strlen($basedir) > 1 && substr($basedir,-1) != '/') { $basedir .= '/'; } - if ( strlen($directory) > 1 && substr($directory,-1) != '/') { $directory .= '/'; } - if ( $this->AddEmbeddedImage($basedir.$directory.$filename, md5($filename), $filename, 'base64',$mimeType) ) { - $message = preg_replace("/".$images[1][$i]."=\"".preg_quote($url, '/')."\"/Ui", $images[1][$i]."=\"".$cid."\"", $message); + $ext = pathinfo($filename, PATHINFO_EXTENSION); + $mimeType = self::_mime_types($ext); + if ( strlen($basedir) > 1 && substr($basedir, -1) != '/') { $basedir .= '/'; } + if ( strlen($directory) > 1 && substr($directory, -1) != '/') { $directory .= '/'; } + if ( $this->AddEmbeddedImage($basedir.$directory.$filename, md5($filename), $filename, 'base64', $mimeType) ) { + $message = preg_replace("/".$images[1][$i]."=[\"']".preg_quote($url, '/')."[\"']/Ui", $images[1][$i]."=\"".$cid."\"", $message); } } } } $this->IsHTML(true); $this->Body = $message; - $textMsg = trim(strip_tags(preg_replace('/<(head|title|style|script)[^>]*>.*?<\/\\1>/s','',$message))); - if ( !empty($textMsg) && empty($this->AltBody) ) { - $this->AltBody = html_entity_decode($textMsg); - } - if ( empty($this->AltBody) ) { - $this->AltBody = 'To view this email message, open the email in with HTML compatibility!' . "\n\n"; - } + if (empty($this->AltBody)) { + $textMsg = trim(strip_tags(preg_replace('/<(head|title|style|script)[^>]*>.*?<\/\\1>/s', '', $message))); + if (!empty($textMsg)) { + $this->AltBody = html_entity_decode($textMsg, ENT_QUOTES, $this->CharSet); + } + } + if (empty($this->AltBody)) { + $this->AltBody = 'To view this email message, open it in a program that understands HTML!' . "\n\n"; + } + return $message; } /** - * Gets the mime type of the embedded or inline image + * Gets the MIME type of the embedded or inline image + * @param string File extension * @access public - * @return mime type of ext + * @return string MIME type of ext + * @static */ - public function _mime_types($ext = '') { + public static function _mime_types($ext = '') { $mimes = array( 'hqx' => 'application/mac-binhex40', 'cpt' => 'application/mac-compactpro', @@ -1938,46 +2340,35 @@ class PHPMailer { 'xl' => 'application/excel', 'eml' => 'message/rfc822' ); - return ( ! isset($mimes[strtolower($ext)])) ? 'application/octet-stream' : $mimes[strtolower($ext)]; + return (!isset($mimes[strtolower($ext)])) ? 'application/octet-stream' : $mimes[strtolower($ext)]; } /** - * Set (or reset) Class Objects (variables) - * - * Usage Example: - * $page->set('X-Priority', '3'); - * - * @access public - * @param string $name Parameter Name - * @param mixed $value Parameter Value - * NOTE: will not work with arrays, there are no arrays to set/reset - */ - public function set ( $name, $value = '' ) { - if ( isset($this->$name) ) { - $this->$name = $value; - } else { - $this->SetError('Cannot set or reset variable ' . $name); - return false; - } - } - - /** - * Read a file from a supplied filename and return it. - * - * @access public - * @param string $filename Parameter File Name - */ - public function getFile($filename) { - $return = ''; - if ($fp = fopen($filename, 'rb')) { - while (!feof($fp)) { - $return .= fread($fp, 1024); + * Set (or reset) Class Objects (variables) + * + * Usage Example: + * $page->set('X-Priority', '3'); + * + * @access public + * @param string $name Parameter Name + * @param mixed $value Parameter Value + * NOTE: will not work with arrays, there are no arrays to set/reset + * @todo Should this not be using __set() magic function? + */ + public function set($name, $value = '') { + try { + if (isset($this->$name) ) { + $this->$name = $value; + } else { + throw new phpmailerException($this->Lang('variable_set') . $name, self::STOP_CRITICAL); + } + } catch (Exception $e) { + $this->SetError($e->getMessage()); + if ($e->getCode() == self::STOP_CRITICAL) { + return false; } - fclose($fp); - return $return; - } else { - return false; } + return true; } /** @@ -1987,10 +2378,9 @@ class PHPMailer { * @return string */ public function SecureHeader($str) { - $str = trim($str); - $str = str_replace("\r", "", $str); - $str = str_replace("\n", "", $str); - return $str; + $str = str_replace("\r", '', $str); + $str = str_replace("\n", '', $str); + return trim($str); } /** @@ -2005,6 +2395,138 @@ class PHPMailer { $this->sign_key_file = $key_filename; $this->sign_key_pass = $key_pass; } + + /** + * Set the private key file and password to sign the message. + * + * @access public + * @param string $key_filename Parameter File Name + * @param string $key_pass Password for private key + */ + public function DKIM_QP($txt) { + $tmp = ''; + $line = ''; + for ($i = 0; $i < strlen($txt); $i++) { + $ord = ord($txt[$i]); + if ( ((0x21 <= $ord) && ($ord <= 0x3A)) || $ord == 0x3C || ((0x3E <= $ord) && ($ord <= 0x7E)) ) { + $line .= $txt[$i]; + } else { + $line .= "=".sprintf("%02X", $ord); + } + } + return $line; + } + + /** + * Generate DKIM signature + * + * @access public + * @param string $s Header + */ + public function DKIM_Sign($s) { + $privKeyStr = file_get_contents($this->DKIM_private); + if ($this->DKIM_passphrase != '') { + $privKey = openssl_pkey_get_private($privKeyStr, $this->DKIM_passphrase); + } else { + $privKey = $privKeyStr; + } + if (openssl_sign($s, $signature, $privKey)) { + return base64_encode($signature); + } + } + + /** + * Generate DKIM Canonicalization Header + * + * @access public + * @param string $s Header + */ + public function DKIM_HeaderC($s) { + $s = preg_replace("/\r\n\s+/", " ", $s); + $lines = explode("\r\n", $s); + foreach ($lines as $key => $line) { + list($heading, $value) = explode(":", $line, 2); + $heading = strtolower($heading); + $value = preg_replace("/\s+/", " ", $value) ; // Compress useless spaces + $lines[$key] = $heading.":".trim($value) ; // Don't forget to remove WSP around the value + } + $s = implode("\r\n", $lines); + return $s; + } + + /** + * Generate DKIM Canonicalization Body + * + * @access public + * @param string $body Message Body + */ + public function DKIM_BodyC($body) { + if ($body == '') return "\r\n"; + // stabilize line endings + $body = str_replace("\r\n", "\n", $body); + $body = str_replace("\n", "\r\n", $body); + // END stabilize line endings + while (substr($body, strlen($body) - 4, 4) == "\r\n\r\n") { + $body = substr($body, 0, strlen($body) - 2); + } + return $body; + } + + /** + * Create the DKIM header, body, as new header + * + * @access public + * @param string $headers_line Header lines + * @param string $subject Subject + * @param string $body Body + */ + public function DKIM_Add($headers_line, $subject, $body) { + $DKIMsignatureType = 'rsa-sha1'; // Signature & hash algorithms + $DKIMcanonicalization = 'relaxed/simple'; // Canonicalization of header/body + $DKIMquery = 'dns/txt'; // Query method + $DKIMtime = time() ; // Signature Timestamp = seconds since 00:00:00 - Jan 1, 1970 (UTC time zone) + $subject_header = "Subject: $subject"; + $headers = explode($this->LE, $headers_line); + foreach($headers as $header) { + if (strpos($header, 'From:') === 0) { + $from_header = $header; + } elseif (strpos($header, 'To:') === 0) { + $to_header = $header; + } + } + $from = str_replace('|', '=7C', $this->DKIM_QP($from_header)); + $to = str_replace('|', '=7C', $this->DKIM_QP($to_header)); + $subject = str_replace('|', '=7C', $this->DKIM_QP($subject_header)) ; // Copied header fields (dkim-quoted-printable + $body = $this->DKIM_BodyC($body); + $DKIMlen = strlen($body) ; // Length of body + $DKIMb64 = base64_encode(pack("H*", sha1($body))) ; // Base64 of packed binary SHA-1 hash of body + $ident = ($this->DKIM_identity == '')? '' : " i=" . $this->DKIM_identity . ";"; + $dkimhdrs = "DKIM-Signature: v=1; a=" . $DKIMsignatureType . "; q=" . $DKIMquery . "; l=" . $DKIMlen . "; s=" . $this->DKIM_selector . ";\r\n". + "\tt=" . $DKIMtime . "; c=" . $DKIMcanonicalization . ";\r\n". + "\th=From:To:Subject;\r\n". + "\td=" . $this->DKIM_domain . ";" . $ident . "\r\n". + "\tz=$from\r\n". + "\t|$to\r\n". + "\t|$subject;\r\n". + "\tbh=" . $DKIMb64 . ";\r\n". + "\tb="; + $toSign = $this->DKIM_HeaderC($from_header . "\r\n" . $to_header . "\r\n" . $subject_header . "\r\n" . $dkimhdrs); + $signed = $this->DKIM_Sign($toSign); + return "X-PHPMAILER-DKIM: phpmailer.worxware.com\r\n".$dkimhdrs.$signed."\r\n"; + } + + protected function doCallback($isSent, $to, $cc, $bcc, $subject, $body) { + if (!empty($this->action_function) && function_exists($this->action_function)) { + $params = array($isSent, $to, $cc, $bcc, $subject, $body); + call_user_func_array($this->action_function, $params); + } + } } +class phpmailerException extends Exception { + public function errorMessage() { + $errorMsg = '' . $this->getMessage() . "
    \n"; + return $errorMsg; + } +} ?> diff --git a/include/phpmailer/class.smtp.php b/include/phpmailer/class.smtp.php index c427d145..9ede6ee9 100644 --- a/include/phpmailer/class.smtp.php +++ b/include/phpmailer/class.smtp.php @@ -1,58 +1,17 @@ do_debug = 0; } - /************************************************************* - * CONNECTION FUNCTIONS * - ***********************************************************/ + ///////////////////////////////////////////////// + // CONNECTION FUNCTIONS + ///////////////////////////////////////////////// /** * Connect to the server specified on the port specified. @@ -139,16 +112,13 @@ class SMTP { * @access public * @return bool */ - public function Connect($host,$port=0,$tval=30) { - /* set the error val to null so there is no confusion */ + public function Connect($host, $port = 0, $tval = 30) { + // set the error val to null so there is no confusion $this->error = null; - /* make sure we are __not__ connected */ + // make sure we are __not__ connected if($this->connected()) { - /* ok we are connected! what should we do? - * for now we will just give an error saying we - * are already connected - */ + // already connected, generate error $this->error = array("error" => "Already connected to a server"); return false; } @@ -157,42 +127,38 @@ class SMTP { $port = $this->SMTP_PORT; } - /* connect to the smtp server */ - $this->smtp_conn = fsockopen($host, // the host of the server + // connect to the smtp server + $this->smtp_conn = @fsockopen($host, // the host of the server $port, // the port to use $errno, // error number if any $errstr, // error message if any $tval); // give up after ? secs - /* verify we connected properly */ - if(empty($this->smtp_conn)) - { + // verify we connected properly + if(empty($this->smtp_conn)) { $GLOBALS['log']->fatal("SMTP -> ERROR: Failed to connect to server. Code: $errno Reply: $errstr "); + if($this->do_debug >= 1) { + echo "SMTP -> ERROR: " . $this->error["error"] . ": $errstr ($errno)" . $this->CRLF . '
    '; + } return false; } - /* sometimes the SMTP server takes a little longer to respond - * so we will give it a longer timeout for the first read - * - Windows still does not have support for this timeout function - */ + // SMTP server can take longer to respond, give longer timeout for first read + // Windows does not have support for this timeout function if(substr(PHP_OS, 0, 3) != "WIN") socket_set_timeout($this->smtp_conn, $tval, 0); - /* get any announcement stuff */ + // get any announcement $announce = $this->get_lines(); - /* set the timeout of any socket functions at 1/10 of a second */ - //if(function_exists("socket_set_timeout")) - // socket_set_timeout($this->smtp_conn, 0, 100000); - if($this->do_debug >= 2) { - echo "SMTP -> FROM SERVER:" . $this->CRLF . $announce; + echo "SMTP -> FROM SERVER:" . $announce . $this->CRLF . '
    '; } return true; } /** - * Initiate a TSL communication with the server. + * Initiate a TLS communication with the server. * * SMTP CODE 220 Ready to start TLS * SMTP CODE 501 Syntax error (no parameters allowed) @@ -214,16 +180,21 @@ class SMTP { $code = substr($rply,0,3); if($this->do_debug >= 2) { - echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; + echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '
    '; } - if($code != 220) - { - $GLOBALS['log']->fatal("SMTP -> ERROR: STARTTLS not accepted from server. Code: $code Reply: $rply "); + if($code != 220) { + $this->error = + array("error" => "STARTTLS not accepted from server", + "smtp_code" => $code, + "smtp_msg" => substr($rply,4)); + if($this->do_debug >= 1) { + echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
    '; + } return false; } - //Begin encrypted connection + // Begin encrypted connection if(!stream_socket_enable_crypto($this->smtp_conn, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) { return false; } @@ -244,9 +215,11 @@ class SMTP { $rply = $this->get_lines(); $code = substr($rply,0,3); - if($code != 334) - { + if($code != 334) { $GLOBALS['log']->fatal("SMTP -> ERROR:AUTH not accepted from server. Code: $code Reply: $rply"); + if($this->do_debug >= 1) { + echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
    '; + } return false; } @@ -256,22 +229,26 @@ class SMTP { $rply = $this->get_lines(); $code = substr($rply,0,3); - if($code != 334) - { + if($code != 334) { $GLOBALS['log']->fatal("SMTP -> ERROR:Username not accepted from server. Code: $code Reply: $rply "); + if($this->do_debug >= 1) { + echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
    '; + } return false; } - - $password = from_html($password); + // Send encoded password + $password = from_html($password); fputs($this->smtp_conn, base64_encode($password) . $this->CRLF); $rply = $this->get_lines(); $code = substr($rply,0,3); - if($code != 235) - { + if($code != 235) { $GLOBALS['log']->fatal("SMTP -> ERROR:Password not accepted from server. Code: $code Reply: $rply "); + if($this->do_debug >= 1) { + echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
    '; + } return false; } @@ -287,11 +264,9 @@ class SMTP { if(!empty($this->smtp_conn)) { $sock_status = socket_get_status($this->smtp_conn); if($sock_status["eof"]) { - // hmm this is an odd situation... the socket is - // valid but we are not connected anymore + // the socket is valid but we are not connected if($this->do_debug >= 1) { - echo "SMTP -> NOTICE:" . $this->CRLF . - "EOF caught while checking if connected"; + echo "SMTP -> NOTICE:" . $this->CRLF . "EOF caught while checking if connected"; } $this->Close(); return false; @@ -318,9 +293,9 @@ class SMTP { } } - /*************************************************************** - * SMTP COMMANDS * - *************************************************************/ + ///////////////////////////////////////////////// + // SMTP COMMANDS + ///////////////////////////////////////////////// /** * Issues a data command and sends the msg_data to the server @@ -356,7 +331,7 @@ class SMTP { $code = substr($rply,0,3); if($this->do_debug >= 2) { - echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; + echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '
    '; } if($code != 354) { @@ -365,8 +340,7 @@ class SMTP { "smtp_code" => $code, "smtp_msg" => substr($rply,4)); if($this->do_debug >= 1) { - echo "SMTP -> ERROR: " . $this->error["error"] . - ": " . $rply . $this->CRLF; + echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
    '; } return false; } @@ -379,7 +353,7 @@ class SMTP { * each of those into smaller lines to fit within the limit. * in addition we will be looking for lines that start with * a period '.' and append and additional period '.' to that - * line. NOTE: this does not count towards are limit. + * line. NOTE: this does not count towards limit. */ // normalize the line breaks so we know the explode works @@ -395,6 +369,7 @@ class SMTP { * and we can process all lines before a blank "" line as * headers. */ + $field = substr($lines[0],0,strpos($lines[0],":")); $in_headers = false; if(!empty($field) && !strstr($field," ")) { @@ -422,8 +397,7 @@ class SMTP { $line = substr($line,$pos + 1); } - /* if we are processing headers we need to - * add a LWSP-char to the front of the new line + /* if processing headers add a LWSP-char to the front of new line * rfc 822 on long msg headers */ if($in_headers) { @@ -432,7 +406,7 @@ class SMTP { } $lines_out[] = $line; - // now send the lines to the server + // send the lines to the server while(list(,$line_out) = @each($lines_out)) { if(strlen($line_out) > 0) { @@ -444,15 +418,14 @@ class SMTP { } } - // ok all the message data has been sent so lets get this - // over with aleady + // message data has been sent fputs($this->smtp_conn, $this->CRLF . "." . $this->CRLF); $rply = $this->get_lines(); $code = substr($rply,0,3); if($this->do_debug >= 2) { - echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; + echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '
    '; } if($code != 250) { @@ -461,69 +434,13 @@ class SMTP { "smtp_code" => $code, "smtp_msg" => substr($rply,4)); if($this->do_debug >= 1) { - echo "SMTP -> ERROR: " . $this->error["error"] . - ": " . $rply . $this->CRLF; + echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
    '; } return false; } return true; } - /** - * Expand takes the name and asks the server to list all the - * people who are members of the _list_. Expand will return - * back and array of the result or false if an error occurs. - * Each value in the array returned has the format of: - * [ ] - * The definition of is defined in rfc 821 - * - * Implements rfc 821: EXPN - * - * SMTP CODE SUCCESS: 250 - * SMTP CODE FAILURE: 550 - * SMTP CODE ERROR : 500,501,502,504,421 - * @access public - * @return string array - */ - public function Expand($name) { - $this->error = null; // so no confusion is caused - - if(!$this->connected()) { - $this->error = array( - "error" => "Called Expand() without being connected"); - return false; - } - - fputs($this->smtp_conn,"EXPN " . $name . $this->CRLF); - - $rply = $this->get_lines(); - $code = substr($rply,0,3); - - if($this->do_debug >= 2) { - echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; - } - - if($code != 250) { - $this->error = - array("error" => "EXPN not accepted from server", - "smtp_code" => $code, - "smtp_msg" => substr($rply,4)); - if($this->do_debug >= 1) { - echo "SMTP -> ERROR: " . $this->error["error"] . - ": " . $rply . $this->CRLF; - } - return false; - } - - // parse the reply and place in our array to return to user - $entries = explode($this->CRLF,$rply); - while(list(,$l) = @each($entries)) { - $list[] = substr($l,4); - } - - return $list; - } - /** * Sends the HELO command to the smtp server. * This makes sure that we and the server are in @@ -536,7 +453,7 @@ class SMTP { * @access public * @return bool */ - public function Hello($host="") { + public function Hello($host = '') { $this->error = null; // so no confusion is caused if(!$this->connected()) { @@ -545,19 +462,17 @@ class SMTP { return false; } - // if a hostname for the HELO was not specified determine - //a suitable one to send + // if hostname for HELO was not specified send default if(empty($host)) { - // we need to determine some sort of appopiate default - // to send to the server + // determine appropriate default to send to server $host = "localhost"; } // Send extended hello first (RFC 2821) - if(!$this->SendHello("EHLO", $host)) - { - if(!$this->SendHello("HELO", $host)) - return false; + if(!$this->SendHello("EHLO", $host)) { + if(!$this->SendHello("HELO", $host)) { + return false; + } } return true; @@ -575,71 +490,23 @@ class SMTP { $code = substr($rply,0,3); if($this->do_debug >= 2) { - echo "SMTP -> FROM SERVER: " . $this->CRLF . $rply; - } - - if($code != 250) - { - $GLOBALS['log']->fatal("SMTP -> ERROR: $hello not accepted from server. Code: $code, Reply: $rply"); - return false; - } - - $this->helo_rply = $rply; - - return true; - } - - /** - * Gets help information on the keyword specified. If the keyword - * is not specified then returns generic help, ussually contianing - * A list of keywords that help is available on. This function - * returns the results back to the user. It is up to the user to - * handle the returned data. If an error occurs then false is - * returned with $this->error set appropiately. - * - * Implements rfc 821: HELP [ ] - * - * SMTP CODE SUCCESS: 211,214 - * SMTP CODE ERROR : 500,501,502,504,421 - * @access public - * @return string - */ - public function Help($keyword="") { - $this->error = null; // to avoid confusion - - if(!$this->connected()) { - $this->error = array( - "error" => "Called Help() without being connected"); - return false; - } - - $extra = ""; - if(!empty($keyword)) { - $extra = " " . $keyword; - } - - fputs($this->smtp_conn,"HELP" . $extra . $this->CRLF); - - $rply = $this->get_lines(); - $code = substr($rply,0,3); - - if($this->do_debug >= 2) { - echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; + echo "SMTP -> FROM SERVER: " . $rply . $this->CRLF . '
    '; } - if($code != 211 && $code != 214) { + if($code != 250) { $this->error = - array("error" => "HELP not accepted from server", + array("error" => $hello . " not accepted from server", "smtp_code" => $code, "smtp_msg" => substr($rply,4)); if($this->do_debug >= 1) { - echo "SMTP -> ERROR: " . $this->error["error"] . - ": " . $rply . $this->CRLF; + echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
    '; } return false; } - return $rply; + $this->helo_rply = $rply; + + return true; } /** @@ -672,53 +539,16 @@ class SMTP { $code = substr($rply,0,3); if($this->do_debug >= 2) { - echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; - } - - if($code != 250) - { - $GLOBALS['log']->fatal("SMTP -> ERROR: MAIL not accepted from server. Code: $code Reply: $rply "); - return false; - } - return true; - } - - /** - * Sends the command NOOP to the SMTP server. - * - * Implements from rfc 821: NOOP - * - * SMTP CODE SUCCESS: 250 - * SMTP CODE ERROR : 500, 421 - * @access public - * @return bool - */ - public function Noop() { - $this->error = null; // so no confusion is caused - - if(!$this->connected()) { - $this->error = array( - "error" => "Called Noop() without being connected"); - return false; - } - - fputs($this->smtp_conn,"NOOP" . $this->CRLF); - - $rply = $this->get_lines(); - $code = substr($rply,0,3); - - if($this->do_debug >= 2) { - echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; + echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '
    '; } if($code != 250) { $this->error = - array("error" => "NOOP not accepted from server", + array("error" => "MAIL not accepted from server", "smtp_code" => $code, "smtp_msg" => substr($rply,4)); if($this->do_debug >= 1) { - echo "SMTP -> ERROR: " . $this->error["error"] . - ": " . $rply . $this->CRLF; + echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
    '; } return false; } @@ -736,7 +566,7 @@ class SMTP { * @access public * @return bool */ - public function Quit($close_on_error=true) { + public function Quit($close_on_error = true) { $this->error = null; // so there is no confusion if(!$this->connected()) { @@ -752,7 +582,7 @@ class SMTP { $byemsg = $this->get_lines(); if($this->do_debug >= 2) { - echo "SMTP -> FROM SERVER:" . $this->CRLF . $byemsg; + echo "SMTP -> FROM SERVER:" . $byemsg . $this->CRLF . '
    '; } $rval = true; @@ -766,8 +596,7 @@ class SMTP { "smtp_rply" => substr($byemsg,4)); $rval = false; if($this->do_debug >= 1) { - echo "SMTP -> ERROR: " . $e["error"] . ": " . - $byemsg . $this->CRLF; + echo "SMTP -> ERROR: " . $e["error"] . ": " . $byemsg . $this->CRLF . '
    '; } } @@ -805,12 +634,14 @@ class SMTP { $code = substr($rply,0,3); if($this->do_debug >= 2) { - echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; + echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '
    '; } - if($code != 250 && $code != 251) - { + if($code != 250 && $code != 251) { $GLOBALS['log']->fatal("SMTP -> ERROR: RCPT not accepted from server. Code: $code Reply: $rply "); + if($this->do_debug >= 1) { + echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
    '; + } return false; } return true; @@ -843,7 +674,7 @@ class SMTP { $code = substr($rply,0,3); if($this->do_debug >= 2) { - echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; + echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '
    '; } if($code != 250) { @@ -852,8 +683,7 @@ class SMTP { "smtp_code" => $code, "smtp_msg" => substr($rply,4)); if($this->do_debug >= 1) { - echo "SMTP -> ERROR: " . $this->error["error"] . - ": " . $rply . $this->CRLF; + echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
    '; } return false; } @@ -861,48 +691,6 @@ class SMTP { return true; } - /** - * Starts a mail transaction from the email address specified in - * $from. Returns true if successful or false otherwise. If True - * the mail transaction is started and then one or more Recipient - * commands may be called followed by a Data command. This command - * will send the message to the users terminal if they are logged - * in. - * - * Implements rfc 821: SEND FROM: - * - * SMTP CODE SUCCESS: 250 - * SMTP CODE SUCCESS: 552,451,452 - * SMTP CODE SUCCESS: 500,501,502,421 - * @access public - * @return bool - */ - public function Send($from) { - $this->error = null; // so no confusion is caused - - if(!$this->connected()) { - $this->error = array( - "error" => "Called Send() without being connected"); - return false; - } - - fputs($this->smtp_conn,"SEND FROM:" . $from . $this->CRLF); - - $rply = $this->get_lines(); - $code = substr($rply,0,3); - - if($this->do_debug >= 2) { - echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; - } - - if($code != 250) - { - $GLOBALS['log']->fatal("SMTP -> ERROR:SEND not accepted from server. Code:$code Reply:$rply"); - return false; - } - return true; - } - /** * Starts a mail transaction from the email address specified in * $from. Returns true if successful or false otherwise. If True @@ -934,7 +722,7 @@ class SMTP { $code = substr($rply,0,3); if($this->do_debug >= 2) { - echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; + echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '
    '; } if($code != 250) { @@ -943,56 +731,7 @@ class SMTP { "smtp_code" => $code, "smtp_msg" => substr($rply,4)); if($this->do_debug >= 1) { - echo "SMTP -> ERROR: " . $this->error["error"] . - ": " . $rply . $this->CRLF; - } - return false; - } - return true; - } - - /** - * Starts a mail transaction from the email address specified in - * $from. Returns true if successful or false otherwise. If True - * the mail transaction is started and then one or more Recipient - * commands may be called followed by a Data command. This command - * will send the message to the users terminal if they are logged - * in or mail it to them if they are not. - * - * Implements rfc 821: SOML FROM: - * - * SMTP CODE SUCCESS: 250 - * SMTP CODE SUCCESS: 552,451,452 - * SMTP CODE SUCCESS: 500,501,502,421 - * @access public - * @return bool - */ - public function SendOrMail($from) { - $this->error = null; // so no confusion is caused - - if(!$this->connected()) { - $this->error = array( - "error" => "Called SendOrMail() without being connected"); - return false; - } - - fputs($this->smtp_conn,"SOML FROM:" . $from . $this->CRLF); - - $rply = $this->get_lines(); - $code = substr($rply,0,3); - - if($this->do_debug >= 2) { - echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; - } - - if($code != 250) { - $this->error = - array("error" => "SOML not accepted from server", - "smtp_code" => $code, - "smtp_msg" => substr($rply,4)); - if($this->do_debug >= 1) { - echo "SMTP -> ERROR: " . $this->error["error"] . - ": " . $rply . $this->CRLF; + echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
    '; } return false; } @@ -1016,59 +755,23 @@ class SMTP { $this->error = array("error" => "This method, TURN, of the SMTP ". "is not implemented"); if($this->do_debug >= 1) { - echo "SMTP -> NOTICE: " . $this->error["error"] . $this->CRLF; + echo "SMTP -> NOTICE: " . $this->error["error"] . $this->CRLF . '
    '; } return false; } /** - * Verifies that the name is recognized by the server. - * Returns false if the name could not be verified otherwise - * the response from the server is returned. - * - * Implements rfc 821: VRFY - * - * SMTP CODE SUCCESS: 250,251 - * SMTP CODE FAILURE: 550,551,553 - * SMTP CODE ERROR : 500,501,502,421 - * @access public - * @return int - */ - public function Verify($name) { - $this->error = null; // so no confusion is caused - - if(!$this->connected()) { - $this->error = array( - "error" => "Called Verify() without being connected"); - return false; - } - - fputs($this->smtp_conn,"VRFY " . $name . $this->CRLF); - - $rply = $this->get_lines(); - $code = substr($rply,0,3); - - if($this->do_debug >= 2) { - echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; - } - - if($code != 250 && $code != 251) { - $this->error = - array("error" => "VRFY failed on name '$name'", - "smtp_code" => $code, - "smtp_msg" => substr($rply,4)); - if($this->do_debug >= 1) { - echo "SMTP -> ERROR: " . $this->error["error"] . - ": " . $rply . $this->CRLF; - } - return false; - } - return $rply; + * Get the current error + * @access public + * @return array + */ + public function getError() { + return $this->error; } - /******************************************************************* - * INTERNAL FUNCTIONS * - ******************************************************************/ + ///////////////////////////////////////////////// + // INTERNAL FUNCTIONS + ///////////////////////////////////////////////// /** * Read in as many lines as possible @@ -1081,19 +784,17 @@ class SMTP { */ private function get_lines() { $data = ""; - while($str = @fgets($this->smtp_conn,515)) { + while(!feof($this->smtp_conn)) { + $str = @fgets($this->smtp_conn,515); if($this->do_debug >= 4) { - echo "SMTP -> get_lines(): \$data was \"$data\"" . - $this->CRLF; - echo "SMTP -> get_lines(): \$str is \"$str\"" . - $this->CRLF; + echo "SMTP -> get_lines(): \$data was \"$data\"" . $this->CRLF . '
    '; + echo "SMTP -> get_lines(): \$str is \"$str\"" . $this->CRLF . '
    '; } $data .= $str; if($this->do_debug >= 4) { - echo "SMTP -> get_lines(): \$data is \"$data\"" . $this->CRLF; + echo "SMTP -> get_lines(): \$data is \"$data\"" . $this->CRLF . '
    '; } - // if the 4th character is a space then we are done reading - // so just break the loop + // if 4th character is a space, we are done reading, break the loop if(substr($str,3,1) == " ") { break; } } return $data; @@ -1101,5 +802,4 @@ class SMTP { } - - ?> +?> diff --git a/include/phpmailer/extras/htmlfilter.php b/include/phpmailer/extras/htmlfilter.php new file mode 100644 index 00000000..d75447de --- /dev/null +++ b/include/phpmailer/extras/htmlfilter.php @@ -0,0 +1,861 @@ + + * @Version 1.1 ($Date: 2011-07-04 14:02:23 -0400 (Mon, 04 Jul 2011) $) + */ + +/** + * @Author Jim Jagielski + */ + +/** + * This function returns the final tag out of the tag name, an array + * of attributes, and the type of the tag. This function is called by + * tln_sanitize internally. + * + * @param $tagname the name of the tag. + * @param $attary the array of attributes and their values + * @param $tagtype The type of the tag (see in comments). + * @return a string with the final tag representation. + */ +function tln_tagprint($tagname, $attary, $tagtype){ + $me = 'tln_tagprint'; + if ($tagtype == 2){ + $fulltag = ''; + } else { + $fulltag = '<' . $tagname; + if (is_array($attary) && sizeof($attary)){ + $atts = Array(); + while (list($attname, $attvalue) = each($attary)){ + array_push($atts, "$attname=$attvalue"); + } + $fulltag .= ' ' . join(' ', $atts); + } + if ($tagtype == 3){ + $fulltag .= ' /'; + } + $fulltag .= '>'; + } + return $fulltag; +} + +/** + * A small helper function to use with array_walk. Modifies a by-ref + * value and makes it lowercase. + * + * @param $val a value passed by-ref. + * @return void since it modifies a by-ref value. + */ +function tln_casenormalize(&$val){ + $val = strtolower($val); +} + +/** + * This function skips any whitespace from the current position within + * a string and to the next non-whitespace value. + * + * @param $body the string + * @param $offset the offset within the string where we should start + * looking for the next non-whitespace character. + * @return the location within the $body where the next + * non-whitespace char is located. + */ +function tln_skipspace($body, $offset){ + $me = 'tln_skipspace'; + preg_match('/^(\s*)/s', substr($body, $offset), $matches); + if (sizeof($matches[1])){ + $count = strlen($matches[1]); + $offset += $count; + } + return $offset; +} + +/** + * This function looks for the next character within a string. It's + * really just a glorified "strpos", except it catches the failures + * nicely. + * + * @param $body The string to look for needle in. + * @param $offset Start looking from this position. + * @param $needle The character/string to look for. + * @return location of the next occurance of the needle, or + * strlen($body) if needle wasn't found. + */ +function tln_findnxstr($body, $offset, $needle){ + $me = 'tln_findnxstr'; + $pos = strpos($body, $needle, $offset); + if ($pos === FALSE){ + $pos = strlen($body); + } + return $pos; +} + +/** + * This function takes a PCRE-style regexp and tries to match it + * within the string. + * + * @param $body The string to look for needle in. + * @param $offset Start looking from here. + * @param $reg A PCRE-style regex to match. + * @return Returns a false if no matches found, or an array + * with the following members: + * - integer with the location of the match within $body + * - string with whatever content between offset and the match + * - string with whatever it is we matched + */ +function tln_findnxreg($body, $offset, $reg){ + $me = 'tln_findnxreg'; + $matches = Array(); + $retarr = Array(); + $preg_rule = '%^(.*?)(' . $reg . ')%s'; + preg_match($preg_rule, substr($body, $offset), $matches); + if (!isset($matches[0])){ + $retarr = false; + } else { + $retarr[0] = $offset + strlen($matches[1]); + $retarr[1] = $matches[1]; + $retarr[2] = $matches[2]; + } + return $retarr; +} + +/** + * This function looks for the next tag. + * + * @param $body String where to look for the next tag. + * @param $offset Start looking from here. + * @return false if no more tags exist in the body, or + * an array with the following members: + * - string with the name of the tag + * - array with attributes and their values + * - integer with tag type (1, 2, or 3) + * - integer where the tag starts (starting "<") + * - integer where the tag ends (ending ">") + * first three members will be false, if the tag is invalid. + */ +function tln_getnxtag($body, $offset){ + $me = 'tln_getnxtag'; + if ($offset > strlen($body)){ + return false; + } + $lt = tln_findnxstr($body, $offset, '<'); + if ($lt == strlen($body)){ + return false; + } + /** + * We are here: + * blah blah + * \---------^ + */ + $pos = tln_skipspace($body, $lt + 1); + if ($pos >= strlen($body)){ + return Array(false, false, false, $lt, strlen($body)); + } + /** + * There are 3 kinds of tags: + * 1. Opening tag, e.g.: + * + * 2. Closing tag, e.g.: + * + * 3. XHTML-style content-less tag, e.g.: + * + */ + $tagtype = false; + switch (substr($body, $pos, 1)){ + case '/': + $tagtype = 2; + $pos++; + break; + case '!': + /** + * A comment or an SGML declaration. + */ + if (substr($body, $pos+1, 2) == '--'){ + $gt = strpos($body, '-->', $pos); + if ($gt === false){ + $gt = strlen($body); + } else { + $gt += 2; + } + return Array(false, false, false, $lt, $gt); + } else { + $gt = tln_findnxstr($body, $pos, '>'); + return Array(false, false, false, $lt, $gt); + } + break; + default: + /** + * Assume tagtype 1 for now. If it's type 3, we'll switch values + * later. + */ + $tagtype = 1; + break; + } + + $tag_start = $pos; + $tagname = ''; + /** + * Look for next [\W-_], which will indicate the end of the tag name. + */ + $regary = tln_findnxreg($body, $pos, '[^\w\-_]'); + if ($regary == false){ + return Array(false, false, false, $lt, strlen($body)); + } + list($pos, $tagname, $match) = $regary; + $tagname = strtolower($tagname); + + /** + * $match can be either of these: + * '>' indicating the end of the tag entirely. + * '\s' indicating the end of the tag name. + * '/' indicating that this is type-3 xhtml tag. + * + * Whatever else we find there indicates an invalid tag. + */ + switch ($match){ + case '/': + /** + * This is an xhtml-style tag with a closing / at the + * end, like so: . Check if it's followed + * by the closing bracket. If not, then this tag is invalid + */ + if (substr($body, $pos, 2) == '/>'){ + $pos++; + $tagtype = 3; + } else { + $gt = tln_findnxstr($body, $pos, '>'); + $retary = Array(false, false, false, $lt, $gt); + return $retary; + } + case '>': + return Array($tagname, false, $tagtype, $lt, $pos); + break; + default: + /** + * Check if it's whitespace + */ + if (preg_match('/\s/', $match)){ + } else { + /** + * This is an invalid tag! Look for the next closing ">". + */ + $gt = tln_findnxstr($body, $lt, '>'); + return Array(false, false, false, $lt, $gt); + } + } + + /** + * At this point we're here: + * + * \-------^ + * + * At this point we loop in order to find all attributes. + */ + $attname = ''; + $atttype = false; + $attary = Array(); + + while ($pos <= strlen($body)){ + $pos = tln_skipspace($body, $pos); + if ($pos == strlen($body)){ + /** + * Non-closed tag. + */ + return Array(false, false, false, $lt, $pos); + } + /** + * See if we arrived at a ">" or "/>", which means that we reached + * the end of the tag. + */ + $matches = Array(); + preg_match('%^(\s*)(>|/>)%s', substr($body, $pos), $matches); + if (isset($matches[0]) && $matches[0]){ + /** + * Yep. So we did. + */ + $pos += strlen($matches[1]); + if ($matches[2] == '/>'){ + $tagtype = 3; + $pos++; + } + return Array($tagname, $attary, $tagtype, $lt, $pos); + } + + /** + * There are several types of attributes, with optional + * [:space:] between members. + * Type 1: + * attrname[:space:]=[:space:]'CDATA' + * Type 2: + * attrname[:space:]=[:space:]"CDATA" + * Type 3: + * attr[:space:]=[:space:]CDATA + * Type 4: + * attrname + * + * We leave types 1 and 2 the same, type 3 we check for + * '"' and convert to """ if needed, then wrap in + * double quotes. Type 4 we convert into: + * attrname="yes". + */ + $regary = tln_findnxreg($body, $pos, '[^\w\-_]'); + if ($regary == false){ + /** + * Looks like body ended before the end of tag. + */ + return Array(false, false, false, $lt, strlen($body)); + } + list($pos, $attname, $match) = $regary; + $attname = strtolower($attname); + /** + * We arrived at the end of attribute name. Several things possible + * here: + * '>' means the end of the tag and this is attribute type 4 + * '/' if followed by '>' means the same thing as above + * '\s' means a lot of things -- look what it's followed by. + * anything else means the attribute is invalid. + */ + switch($match){ + case '/': + /** + * This is an xhtml-style tag with a closing / at the + * end, like so: . Check if it's followed + * by the closing bracket. If not, then this tag is invalid + */ + if (substr($body, $pos, 2) == '/>'){ + $pos++; + $tagtype = 3; + } else { + $gt = tln_findnxstr($body, $pos, '>'); + $retary = Array(false, false, false, $lt, $gt); + return $retary; + } + case '>': + $attary{$attname} = '"yes"'; + return Array($tagname, $attary, $tagtype, $lt, $pos); + break; + default: + /** + * Skip whitespace and see what we arrive at. + */ + $pos = tln_skipspace($body, $pos); + $char = substr($body, $pos, 1); + /** + * Two things are valid here: + * '=' means this is attribute type 1 2 or 3. + * \w means this was attribute type 4. + * anything else we ignore and re-loop. End of tag and + * invalid stuff will be caught by our checks at the beginning + * of the loop. + */ + if ($char == '='){ + $pos++; + $pos = tln_skipspace($body, $pos); + /** + * Here are 3 possibilities: + * "'" attribute type 1 + * '"' attribute type 2 + * everything else is the content of tag type 3 + */ + $quot = substr($body, $pos, 1); + if ($quot == '\''){ + $regary = tln_findnxreg($body, $pos+1, '\''); + if ($regary == false){ + return Array(false, false, false, $lt, strlen($body)); + } + list($pos, $attval, $match) = $regary; + $pos++; + $attary{$attname} = '\'' . $attval . '\''; + } else if ($quot == '"'){ + $regary = tln_findnxreg($body, $pos+1, '\"'); + if ($regary == false){ + return Array(false, false, false, $lt, strlen($body)); + } + list($pos, $attval, $match) = $regary; + $pos++; + $attary{$attname} = '"' . $attval . '"'; + } else { + /** + * These are hateful. Look for \s, or >. + */ + $regary = tln_findnxreg($body, $pos, '[\s>]'); + if ($regary == false){ + return Array(false, false, false, $lt, strlen($body)); + } + list($pos, $attval, $match) = $regary; + /** + * If it's ">" it will be caught at the top. + */ + $attval = preg_replace('/\"/s', '"', $attval); + $attary{$attname} = '"' . $attval . '"'; + } + } else if (preg_match('|[\w/>]|', $char)) { + /** + * That was attribute type 4. + */ + $attary{$attname} = '"yes"'; + } else { + /** + * An illegal character. Find next '>' and return. + */ + $gt = tln_findnxstr($body, $pos, '>'); + return Array(false, false, false, $lt, $gt); + } + } + } + /** + * The fact that we got here indicates that the tag end was never + * found. Return invalid tag indication so it gets stripped. + */ + return Array(false, false, false, $lt, strlen($body)); +} + +/** + * Translates entities into literal values so they can be checked. + * + * @param $attvalue the by-ref value to check. + * @param $regex the regular expression to check against. + * @param $hex whether the entites are hexadecimal. + * @return True or False depending on whether there were matches. + */ +function tln_deent(&$attvalue, $regex, $hex=false){ + $me = 'tln_deent'; + $ret_match = false; + preg_match_all($regex, $attvalue, $matches); + if (is_array($matches) && sizeof($matches[0]) > 0){ + $repl = Array(); + for ($i = 0; $i < sizeof($matches[0]); $i++){ + $numval = $matches[1][$i]; + if ($hex){ + $numval = hexdec($numval); + } + $repl{$matches[0][$i]} = chr($numval); + } + $attvalue = strtr($attvalue, $repl); + return true; + } else { + return false; + } +} + +/** + * This function checks attribute values for entity-encoded values + * and returns them translated into 8-bit strings so we can run + * checks on them. + * + * @param $attvalue A string to run entity check against. + * @return Nothing, modifies a reference value. + */ +function tln_defang(&$attvalue){ + $me = 'tln_defang'; + /** + * Skip this if there aren't ampersands or backslashes. + */ + if (strpos($attvalue, '&') === false + && strpos($attvalue, '\\') === false){ + return; + } + $m = false; + do { + $m = false; + $m = $m || tln_deent($attvalue, '/\�*(\d+);*/s'); + $m = $m || tln_deent($attvalue, '/\�*((\d|[a-f])+);*/si', true); + $m = $m || tln_deent($attvalue, '/\\\\(\d+)/s', true); + } while ($m == true); + $attvalue = stripslashes($attvalue); +} + +/** + * Kill any tabs, newlines, or carriage returns. Our friends the + * makers of the browser with 95% market value decided that it'd + * be funny to make "java[tab]script" be just as good as "javascript". + * + * @param attvalue The attribute value before extraneous spaces removed. + * @return attvalue Nothing, modifies a reference value. + */ +function tln_unspace(&$attvalue){ + $me = 'tln_unspace'; + if (strcspn($attvalue, "\t\r\n\0 ") != strlen($attvalue)){ + $attvalue = str_replace(Array("\t", "\r", "\n", "\0", " "), + Array('', '', '', '', ''), $attvalue); + } +} + +/** + * This function runs various checks against the attributes. + * + * @param $tagname String with the name of the tag. + * @param $attary Array with all tag attributes. + * @param $rm_attnames See description for tln_sanitize + * @param $bad_attvals See description for tln_sanitize + * @param $add_attr_to_tag See description for tln_sanitize + * @return Array with modified attributes. + */ +function tln_fixatts($tagname, + $attary, + $rm_attnames, + $bad_attvals, + $add_attr_to_tag + ){ + $me = 'tln_fixatts'; + while (list($attname, $attvalue) = each($attary)){ + /** + * See if this attribute should be removed. + */ + foreach ($rm_attnames as $matchtag=>$matchattrs){ + if (preg_match($matchtag, $tagname)){ + foreach ($matchattrs as $matchattr){ + if (preg_match($matchattr, $attname)){ + unset($attary{$attname}); + continue; + } + } + } + } + /** + * Remove any backslashes, entities, or extraneous whitespace. + */ + tln_defang($attvalue); + tln_unspace($attvalue); + + /** + * Now let's run checks on the attvalues. + * I don't expect anyone to comprehend this. If you do, + * get in touch with me so I can drive to where you live and + * shake your hand personally. :) + */ + foreach ($bad_attvals as $matchtag=>$matchattrs){ + if (preg_match($matchtag, $tagname)){ + foreach ($matchattrs as $matchattr=>$valary){ + if (preg_match($matchattr, $attname)){ + /** + * There are two arrays in valary. + * First is matches. + * Second one is replacements + */ + list($valmatch, $valrepl) = $valary; + $newvalue = preg_replace($valmatch,$valrepl,$attvalue); + if ($newvalue != $attvalue){ + $attary{$attname} = $newvalue; + } + } + } + } + } + } + /** + * See if we need to append any attributes to this tag. + */ + foreach ($add_attr_to_tag as $matchtag=>$addattary){ + if (preg_match($matchtag, $tagname)){ + $attary = array_merge($attary, $addattary); + } + } + return $attary; +} + +/** + * + * @param $body the string with HTML you wish to filter + * @param $tag_list see description above + * @param $rm_tags_with_content see description above + * @param $self_closing_tags see description above + * @param $force_tag_closing see description above + * @param $rm_attnames see description above + * @param $bad_attvals see description above + * @param $add_attr_to_tag see description above + * @return tln_sanitized html safe to show on your pages. + */ +function tln_sanitize($body, + $tag_list, + $rm_tags_with_content, + $self_closing_tags, + $force_tag_closing, + $rm_attnames, + $bad_attvals, + $add_attr_to_tag + ) +{ + $me = 'tln_sanitize'; + /** + * Normalize rm_tags and rm_tags_with_content. + */ + $rm_tags = array_shift($tag_list); + @array_walk($tag_list, 'tln_casenormalize'); + @array_walk($rm_tags_with_content, 'tln_casenormalize'); + @array_walk($self_closing_tags, 'tln_casenormalize'); + /** + * See if tag_list is of tags to remove or tags to allow. + * false means remove these tags + * true means allow these tags + */ + $curpos = 0; + $open_tags = Array(); + $trusted = "\n"; + $skip_content = false; + /** + * Take care of netscape's stupid javascript entities like + * &{alert('boo')}; + */ + $body = preg_replace('/&(\{.*?\};)/si', '&\\1', $body); + while (($curtag = tln_getnxtag($body, $curpos)) != FALSE){ + list($tagname, $attary, $tagtype, $lt, $gt) = $curtag; + $free_content = substr($body, $curpos, $lt - $curpos); + if ($skip_content == false){ + $trusted .= $free_content; + } else { + } + if ($tagname != FALSE){ + if ($tagtype == 2){ + if ($skip_content == $tagname){ + /** + * Got to the end of tag we needed to remove. + */ + $tagname = false; + $skip_content = false; + } else { + if ($skip_content == false){ + if (isset($open_tags{$tagname}) && + $open_tags{$tagname} > 0){ + $open_tags{$tagname}--; + } else { + $tagname = false; + } + } else { + } + } + } else { + /** + * $rm_tags_with_content + */ + if ($skip_content == false){ + /** + * See if this is a self-closing type and change + * tagtype appropriately. + */ + if ($tagtype == 1 + && in_array($tagname, $self_closing_tags)){ + $tagtype = 3; + } + /** + * See if we should skip this tag and any content + * inside it. + */ + if ($tagtype == 1 + && in_array($tagname, $rm_tags_with_content)){ + $skip_content = $tagname; + } else { + if (($rm_tags == false + && in_array($tagname, $tag_list)) || + ($rm_tags == true + && !in_array($tagname, $tag_list))){ + $tagname = false; + } else { + if ($tagtype == 1){ + if (isset($open_tags{$tagname})){ + $open_tags{$tagname}++; + } else { + $open_tags{$tagname} = 1; + } + } + /** + * This is where we run other checks. + */ + if (is_array($attary) && sizeof($attary) > 0){ + $attary = tln_fixatts($tagname, + $attary, + $rm_attnames, + $bad_attvals, + $add_attr_to_tag); + } + } + } + } else { + } + } + if ($tagname != false && $skip_content == false){ + $trusted .= tln_tagprint($tagname, $attary, $tagtype); + } + } else { + } + $curpos = $gt + 1; + } + $trusted .= substr($body, $curpos, strlen($body) - $curpos); + if ($force_tag_closing == true){ + foreach ($open_tags as $tagname=>$opentimes){ + while ($opentimes > 0){ + $trusted .= ''; + $opentimes--; + } + } + $trusted .= "\n"; + } + $trusted .= "\n"; + return $trusted; +} + +// +// Use the nifty htmlfilter library +// + + +function HTMLFilter($body, $trans_image_path, $block_external_images = false) { + + $tag_list = Array( + false, + "object", + "meta", + "html", + "head", + "base", + "link", + "frame", + "iframe", + "plaintext", + "marquee" + ); + + $rm_tags_with_content = Array( + "script", + "applet", + "embed", + "title", + "frameset", + "xmp", + "xml" + ); + + $self_closing_tags = Array( + "img", + "br", + "hr", + "input", + "outbind" + ); + + $force_tag_closing = true; + + $rm_attnames = Array( + "/.*/" => + Array( + // "/target/i", + "/^on.*/i", + "/^dynsrc/i", + "/^data.*/i", + "/^lowsrc.*/i" + ) + ); + + $bad_attvals = Array( + "/.*/" => + Array( + "/^src|background/i" => + Array( + Array( + "/^([\'\"])\s*\S+script\s*:.*([\'\"])/si", + "/^([\'\"])\s*mocha\s*:*.*([\'\"])/si", + "/^([\'\"])\s*about\s*:.*([\'\"])/si" + ), + Array( + "\\1$trans_image_path\\2", + "\\1$trans_image_path\\2", + "\\1$trans_image_path\\2", + "\\1$trans_image_path\\2" + ) + ), + "/^href|action/i" => + Array( + Array( + "/^([\'\"])\s*\S+script\s*:.*([\'\"])/si", + "/^([\'\"])\s*mocha\s*:*.*([\'\"])/si", + "/^([\'\"])\s*about\s*:.*([\'\"])/si" + ), + Array( + "\\1#\\1", + "\\1#\\1", + "\\1#\\1", + "\\1#\\1" + ) + ), + "/^style/i" => + Array( + Array( + "/expression/i", + "/binding/i", + "/behaviou*r/i", + "/include-source/i", + "/position\s*:\s*absolute/i", + "/url\s*\(\s*([\'\"])\s*\S+script\s*:.*([\'\"])\s*\)/si", + "/url\s*\(\s*([\'\"])\s*mocha\s*:.*([\'\"])\s*\)/si", + "/url\s*\(\s*([\'\"])\s*about\s*:.*([\'\"])\s*\)/si", + "/(.*)\s*:\s*url\s*\(\s*([\'\"]*)\s*\S+script\s*:.*([\'\"]*)\s*\)/si" + ), + Array( + "idiocy", + "idiocy", + "idiocy", + "idiocy", + "", + "url(\\1#\\1)", + "url(\\1#\\1)", + "url(\\1#\\1)", + "url(\\1#\\1)", + "url(\\1#\\1)", + "\\1:url(\\2#\\3)" + ) + ) + ) + ); + + if ($block_external_images){ + array_push($bad_attvals{'/.*/'}{'/^src|background/i'}[0], + '/^([\'\"])\s*https*:.*([\'\"])/si'); + array_push($bad_attvals{'/.*/'}{'/^src|background/i'}[1], + "\\1$trans_image_path\\1"); + array_push($bad_attvals{'/.*/'}{'/^style/i'}[0], + '/url\(([\'\"])\s*https*:.*([\'\"])\)/si'); + array_push($bad_attvals{'/.*/'}{'/^style/i'}[1], + "url(\\1$trans_image_path\\1)"); + } + + $add_attr_to_tag = Array( + "/^a$/i" => + Array('target'=>'"_blank"') + ); + + $trusted = tln_sanitize($body, + $tag_list, + $rm_tags_with_content, + $self_closing_tags, + $force_tag_closing, + $rm_attnames, + $bad_attvals, + $add_attr_to_tag + ); + return $trusted; +} + +?> diff --git a/include/phpmailer/language/phpmailer.lang-ar.php b/include/phpmailer/language/phpmailer.lang-ar.php index 88400b5b..b7c5057d 100644 --- a/include/phpmailer/language/phpmailer.lang-ar.php +++ b/include/phpmailer/language/phpmailer.lang-ar.php @@ -1,48 +1,27 @@ */ - -$PHPMAILER_LANG = array(); - -$PHPMAILER_LANG["provide_address"] = ' íÌÈ Ãä ÊÖÚ Úáì ÇáÃÞá ' . - 'ÚäæÇä ÈÑíÏ ÅáßÊÑæäí ãÓÊÞÈá æÇÍÏ'; -$PHPMAILER_LANG["mailer_not_supported"] = ' ãÑÓá ÇáÈÑíÏ ÛíÑ ãÏÚæã :'; -$PHPMAILER_LANG["execute"] = 'áÇ íãßä ÊäÝíÐ : '; -$PHPMAILER_LANG["instantiate"] = 'áã íÓÊØÚ ÊåíÆÉ ÊÇÈÚ ÇáÈÑíÏ'; -$PHPMAILER_LANG["authenticate"] = 'ÎØà STMP : áã íãáß ÇáÕáÇÍíÉ'; -$PHPMAILER_LANG["from_failed"] = 'ÇáÚäæÇä ÇáãÑÓá ÇáÊÇáí ÝÔá : '; -$PHPMAILER_LANG["recipients_failed"] = 'ÎØà STMP : ' . - 'åÄáÇÁ ÇáãÓÊÞÈáæä ÝÔáæÇ : '; -$PHPMAILER_LANG["data_not_accepted"] = 'ÎØà STMP : ÇáãÚØíÇÊ áã ÊÞÈá .'; -$PHPMAILER_LANG["connect_host"] = 'ÎØà STMP : ÇáÇÊÕÇá ÈãÓÊÖíÝ STMP áã íÊã'; -$PHPMAILER_LANG["file_access"] = 'áÇ íãßä ÇáæÕæá áãáÝ : '; -$PHPMAILER_LANG["file_open"] = 'ÎØà ãáÝ : áã íãßä ÝÊÍ ãáÝ :'; -$PHPMAILER_LANG["encoding"] = 'ÊÔÝíÑ ÛíÑ ãÚÑæÝ : '; -$PHPMAILER_LANG["signing"] = 'ÎØà ÊÓÌíá : '; +* PHPMailer language file: refer to English translation for definitive list +* Arabic Version, UTF-8 +* by : bahjat al mostafa +*/ +$PHPMAILER_LANG['authenticate'] = 'SMTP Error: لم نستطع تأكيد الهوية.'; +$PHPMAILER_LANG['connect_host'] = 'SMTP Error: لم نستطع الاتصال بمخدم SMTP.'; +$PHPMAILER_LANG['data_not_accepted'] = 'SMTP Error: لم يتم قبول المعلومات .'; +//$PHPMAILER_LANG['empty_message'] = 'Message body empty'; +$PHPMAILER_LANG['encoding'] = 'ترميز غير معروف: '; +$PHPMAILER_LANG['execute'] = 'لم أستطع تنفيذ : '; +$PHPMAILER_LANG['file_access'] = 'لم نستطع الوصول للملف: '; +$PHPMAILER_LANG['file_open'] = 'File Error: لم نستطع فتح الملف: '; +$PHPMAILER_LANG['from_failed'] = 'البريد التالي لم نستطع ارسال البريد له : '; +$PHPMAILER_LANG['instantiate'] = 'لم نستطع توفير خدمة البريد.'; +//$PHPMAILER_LANG['invalid_email'] = 'Not sending, email address is invalid: '; +$PHPMAILER_LANG['mailer_not_supported'] = ' mailer غير مدعوم.'; +//$PHPMAILER_LANG['provide_address'] = 'You must provide at least one recipient email address.'; +$PHPMAILER_LANG['recipients_failed'] = 'SMTP Error: الأخطاء التالية ' . + 'فشل في الارسال لكل من : '; +$PHPMAILER_LANG['signing'] = 'خطأ في التوقيع: '; +//$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.'; +//$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: '; +//$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: '; ?> \ No newline at end of file diff --git a/include/phpmailer/language/phpmailer.lang-br.php b/include/phpmailer/language/phpmailer.lang-br.php index 85bfd94c..6afe60b1 100644 --- a/include/phpmailer/language/phpmailer.lang-br.php +++ b/include/phpmailer/language/phpmailer.lang-br.php @@ -1,56 +1,26 @@ \ No newline at end of file diff --git a/include/phpmailer/language/phpmailer.lang-ca.php b/include/phpmailer/language/phpmailer.lang-ca.php index ae69fff8..4a160a21 100644 --- a/include/phpmailer/language/phpmailer.lang-ca.php +++ b/include/phpmailer/language/phpmailer.lang-ca.php @@ -1,55 +1,26 @@ \ No newline at end of file diff --git a/include/phpmailer/language/phpmailer.lang-ch.php b/include/phpmailer/language/phpmailer.lang-ch.php new file mode 100644 index 00000000..31ebd861 --- /dev/null +++ b/include/phpmailer/language/phpmailer.lang-ch.php @@ -0,0 +1,26 @@ + \ No newline at end of file diff --git a/include/phpmailer/language/phpmailer.lang-cz.php b/include/phpmailer/language/phpmailer.lang-cz.php index 6f5f9b06..1c8b2063 100644 --- a/include/phpmailer/language/phpmailer.lang-cz.php +++ b/include/phpmailer/language/phpmailer.lang-cz.php @@ -1,59 +1,25 @@ \ No newline at end of file diff --git a/include/phpmailer/language/phpmailer.lang-de.php b/include/phpmailer/language/phpmailer.lang-de.php index d61da840..b2a76ce1 100644 --- a/include/phpmailer/language/phpmailer.lang-de.php +++ b/include/phpmailer/language/phpmailer.lang-de.php @@ -1,59 +1,25 @@ \ No newline at end of file diff --git a/include/phpmailer/language/phpmailer.lang-dk.php b/include/phpmailer/language/phpmailer.lang-dk.php index 97bb6864..b2625731 100644 --- a/include/phpmailer/language/phpmailer.lang-dk.php +++ b/include/phpmailer/language/phpmailer.lang-dk.php @@ -1,56 +1,26 @@ */ - -$PHPMAILER_LANG = array(); - -$PHPMAILER_LANG["provide_address"] = 'Du skal indtaste mindst en ' . - 'modtagers emailadresse.'; -$PHPMAILER_LANG["mailer_not_supported"] = ' mailer understøttes ikke.'; -$PHPMAILER_LANG["execute"] = 'Kunne ikke køre: '; -$PHPMAILER_LANG["instantiate"] = 'Kunne ikke initialisere email funktionen.'; -$PHPMAILER_LANG["authenticate"] = 'SMTP fejl: Kunne ikke logge pÃ¥.'; -$PHPMAILER_LANG["from_failed"] = 'Følgende afsenderadresse er forkert: '; -$PHPMAILER_LANG["recipients_failed"] = 'SMTP fejl: Følgende' . - 'modtagere er forkerte: '; -$PHPMAILER_LANG["data_not_accepted"] = 'SMTP fejl: Data kunne ikke accepteres.'; -$PHPMAILER_LANG["connect_host"] = 'SMTP fejl: Kunne ikke tilslutte SMTP serveren.'; -$PHPMAILER_LANG["file_access"] = 'Ingen adgang til fil: '; -$PHPMAILER_LANG["file_open"] = 'Fil fejl: Kunne ikke Ã¥bne filen: '; -$PHPMAILER_LANG["encoding"] = 'Ukendt encode-format: '; -$PHPMAILER_LANG["signing"] = 'Signing Error: '; +* PHPMailer language file: refer to English translation for definitive list +* Danish Version +* Author: Mikael Stokkebro +*/ +$PHPMAILER_LANG['authenticate'] = 'SMTP fejl: Kunne ikke logge pÃ¥.'; +$PHPMAILER_LANG['connect_host'] = 'SMTP fejl: Kunne ikke tilslutte SMTP serveren.'; +$PHPMAILER_LANG['data_not_accepted'] = 'SMTP fejl: Data kunne ikke accepteres.'; +//$PHPMAILER_LANG['empty_message'] = 'Message body empty'; +$PHPMAILER_LANG['encoding'] = 'Ukendt encode-format: '; +$PHPMAILER_LANG['execute'] = 'Kunne ikke køre: '; +$PHPMAILER_LANG['file_access'] = 'Ingen adgang til fil: '; +$PHPMAILER_LANG['file_open'] = 'Fil fejl: Kunne ikke Ã¥bne filen: '; +$PHPMAILER_LANG['from_failed'] = 'Følgende afsenderadresse er forkert: '; +$PHPMAILER_LANG['instantiate'] = 'Kunne ikke initialisere email funktionen.'; +//$PHPMAILER_LANG['invalid_email'] = 'Not sending, email address is invalid: '; +$PHPMAILER_LANG['mailer_not_supported'] = ' mailer understøttes ikke.'; +$PHPMAILER_LANG['provide_address'] = 'Du skal indtaste mindst en modtagers emailadresse.'; +$PHPMAILER_LANG['recipients_failed'] = 'SMTP fejl: Følgende modtagere er forkerte: '; +//$PHPMAILER_LANG['signing'] = 'Signing Error: '; +//$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.'; +//$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: '; +//$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: '; ?> \ No newline at end of file diff --git a/include/phpmailer/language/phpmailer.lang-es.php b/include/phpmailer/language/phpmailer.lang-es.php index 1935c77d..69b68174 100644 --- a/include/phpmailer/language/phpmailer.lang-es.php +++ b/include/phpmailer/language/phpmailer.lang-es.php @@ -1,58 +1,26 @@ \ No newline at end of file diff --git a/include/phpmailer/language/phpmailer.lang-et.php b/include/phpmailer/language/phpmailer.lang-et.php index 4b364b98..cf61779b 100644 --- a/include/phpmailer/language/phpmailer.lang-et.php +++ b/include/phpmailer/language/phpmailer.lang-et.php @@ -1,51 +1,26 @@ \ No newline at end of file diff --git a/include/phpmailer/language/phpmailer.lang-fi.php b/include/phpmailer/language/phpmailer.lang-fi.php index 03d3da96..12a845aa 100644 --- a/include/phpmailer/language/phpmailer.lang-fi.php +++ b/include/phpmailer/language/phpmailer.lang-fi.php @@ -1,56 +1,27 @@ \ No newline at end of file diff --git a/include/phpmailer/language/phpmailer.lang-fo.php b/include/phpmailer/language/phpmailer.lang-fo.php index 11db4819..6bd9b0a2 100644 --- a/include/phpmailer/language/phpmailer.lang-fo.php +++ b/include/phpmailer/language/phpmailer.lang-fo.php @@ -1,58 +1,27 @@ \ No newline at end of file diff --git a/include/phpmailer/language/phpmailer.lang-fr.php b/include/phpmailer/language/phpmailer.lang-fr.php index 957b11de..c99ac3ca 100644 --- a/include/phpmailer/language/phpmailer.lang-fr.php +++ b/include/phpmailer/language/phpmailer.lang-fr.php @@ -1,58 +1,25 @@ \ No newline at end of file diff --git a/include/phpmailer/language/phpmailer.lang-hu.php b/include/phpmailer/language/phpmailer.lang-hu.php index 66a116ce..caca0b50 100644 --- a/include/phpmailer/language/phpmailer.lang-hu.php +++ b/include/phpmailer/language/phpmailer.lang-hu.php @@ -1,56 +1,25 @@ \ No newline at end of file diff --git a/include/phpmailer/language/phpmailer.lang-it.php b/include/phpmailer/language/phpmailer.lang-it.php index fd65e65e..fc1fcb8d 100644 --- a/include/phpmailer/language/phpmailer.lang-it.php +++ b/include/phpmailer/language/phpmailer.lang-it.php @@ -1,64 +1,27 @@ */ - -$PHPMAILER_LANG = array(); - -$PHPMAILER_LANG["provide_address"] = 'Deve essere fornito almeno un'. - ' indirizzo ricevente'; -$PHPMAILER_LANG["mailer_not_supported"] = 'Mailer non supportato'; -$PHPMAILER_LANG["execute"] = "Impossibile eseguire l'operazione: "; -$PHPMAILER_LANG["instantiate"] = 'Impossibile istanziare la funzione mail'; -$PHPMAILER_LANG["authenticate"] = 'SMTP Error: Impossibile autenticarsi.'; -$PHPMAILER_LANG["from_failed"] = 'I seguenti indirizzi mittenti hanno'. - ' generato errore: '; -$PHPMAILER_LANG["recipients_failed"] = 'SMTP Error: I seguenti indirizzi'. - 'destinatari hanno generato errore: '; -$PHPMAILER_LANG["data_not_accepted"] = 'SMTP Error: Data non accettati dal'. - 'server.'; -$PHPMAILER_LANG["connect_host"] = 'SMTP Error: Impossibile connettersi'. - ' all\'host SMTP.'; -$PHPMAILER_LANG["file_access"] = 'Impossibile accedere al file: '; -$PHPMAILER_LANG["file_open"] = 'File Error: Impossibile aprire il file: '; -$PHPMAILER_LANG["encoding"] = 'Encoding set dei caratteri sconosciuto: '; -$PHPMAILER_LANG["signing"] = 'Signing Error: '; +* @author Ilias Bartolini +*/ +$PHPMAILER_LANG['authenticate'] = 'SMTP Error: Impossibile autenticarsi.'; +$PHPMAILER_LANG['connect_host'] = 'SMTP Error: Impossibile connettersi all\'host SMTP.'; +$PHPMAILER_LANG['data_not_accepted'] = 'SMTP Error: Data non accettati dal server.'; +//$PHPMAILER_LANG['empty_message'] = 'Message body empty'; +$PHPMAILER_LANG['encoding'] = 'Encoding set dei caratteri sconosciuto: '; +$PHPMAILER_LANG['execute'] = 'Impossibile eseguire l\'operazione: '; +$PHPMAILER_LANG['file_access'] = 'Impossibile accedere al file: '; +$PHPMAILER_LANG['file_open'] = 'File Error: Impossibile aprire il file: '; +$PHPMAILER_LANG['from_failed'] = 'I seguenti indirizzi mittenti hanno generato errore: '; +$PHPMAILER_LANG['instantiate'] = 'Impossibile istanziare la funzione mail'; +//$PHPMAILER_LANG['invalid_email'] = 'Not sending, email address is invalid: '; +$PHPMAILER_LANG['provide_address'] = 'Deve essere fornito almeno un indirizzo ricevente'; +$PHPMAILER_LANG['mailer_not_supported'] = 'Mailer non supportato'; +$PHPMAILER_LANG['recipients_failed'] = 'SMTP Error: I seguenti indirizzi destinatari hanno generato errore: '; +//$PHPMAILER_LANG['signing'] = 'Signing Error: '; +//$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.'; +//$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: '; +//$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: '; ?> \ No newline at end of file diff --git a/include/phpmailer/language/phpmailer.lang-ja.php b/include/phpmailer/language/phpmailer.lang-ja.php index 92e2b666271437a0bb15fb63b59e9a677387c405..63cfb23b6af8f1b467dfbfebc60f0d7834236b05 100644 GIT binary patch literal 1705 zcmb7FTWb?R7=6#LmLF+BusZF$zU?G%uIrPb7mDUy@*O{>xGhf zt8J}?qEuS#kNKLI{tLg|?N-um1ecIxXJ*fwIp=)ep6CzCK`!6ho9iV*7lsBYuP{X_ zRFrD8#7Gfu`-oyi95j*)h*E{?GBJt@U7?0cL5fllpB1^_hSwRvd4pJ&Xg~$ijND*K z<1!pNGeQQr(X}#HlH8QK%za9Zkg_pBUp`;ODZ}m@^<*`l>&@qK2O>JBFJ2zFTDW}r z%K2M8v}Vdo817NSdTx`Gr03e;^&xQc5PpVmqmQ%~#@q87U_XH!2m1@`Yj7{(+m~Qx z;hyU`z8}?-LNL!1%2Jz5)OeE+p?*O42<&2O;=}Lnul{ovpBh>a(iEuYvA{4tb1MiR z;z7V|f*or+-m1S$p(`#GA#WO5--aV zg$YmkT$B=)TWjO3=?Sn4vDT~LRwI_k)xCodZ&&(ACdggp)l#dP%d_nU9wFPCY=9_y zv0z#!L?E05*8uk(!bNlf+#I;C;MOB=I+6bYC<7)k;Qq#_V;A>)dulYYAk9-3WF@PG zVpKdk&bF2sV3*I~aKtiv4B=ADa&dd=#kQRUdmlXp>%cvUp=YvjxzL7U=653xVIvkF zapqc+D+tp1@~*kIhH^AVC%1mS0gJiG&VEKvxTw<#_Y16w+&hADMH-@+h*EGEgM!n9 z`o6;W5RRYZxopybl6CH*b;0VK%h``)82;as^VohVJ(2I|;DXDbX-9j;s z2OPVQ?r?igBTCH23f|gmwC_FWIG$Z3|BOI}Nt%~LQjBRK$G=enOlHV{Qc}fcWIbLr zK_P8(yBSUUCpnumz=MZKGItbfxf=?L_W2tVq_NY5F)FH#?}&IoHzIYaI332C)+}nZ a>4gwysleulAco-E1Ve^@($z6q|EWKeh~{Vj literal 2670 zcmcJR?MqZa6vm&=`&V2fu!5An_KJnQNQR^Z5wR@0>PoIIyKCj2f_9QlRy{-?_8bi@VFkC1ZH*%$+-D=9%ZrIdgSH$CXtY#MG?)l$bo8o;q{} zv@4-L^{ZPs`ucerP_Krld+GDkQ~uhtW!J{HtUs<>d4J3$-#X98L9B!MPiPqXc6tkp z8-hb0YYftNnP=XAPce_D10c<)0`ne%WwSD6s{%7$QiKME4end3REz1pY4 zJFvT=2KHjRy$*vET;kZLC^_1BN`tO4b69MhMlEVm<9ZIPeg?kkAkQZ%>WfCSK)nV= z!3tOhb9~>x)+_HUoO8EYjhfdxIQ(EGTWyWCC-hQpX-|MrVBbE2IarRt##D;d)-=kX zN^tt(cxn*8#ZhMn^|HL>d_ShjYB`NO_8e&O-Pgoe6g3Mzl{GTuX2Cjm3al8rd9Ya* z!*1QgV@Vjg)S=KFhzK2(|j`i^C@uM=sDeKufd%^jt^rnmcMxt&64zF~oY+D_FCG>rRlHV9- zr8+9=@wMfMBtFgpr(-^XZ?uL1_XYjI|M%F-DjHYjkCJ~9|7Ql-O?~Xvut*3qMgqN( zXqEM&V!J=1^(k_;TwY!B{bo9iYnlxA+ONksk1mh=du-S(Hb61&TAoYuZZTaut3>k- zW99??oCB8gO2qa@vd;|d-HaKRqwNlJI@h|vg6MI)i|AKG*&fvcIY`#ws&-Ql}#WKh_E5zvw zylH;}j^ifvO!=%X(;frXH&xd?Vt;A9u-FNcfJ^5#8;^e^`yaB~IaDFWf9A2jg6R|0 diff --git a/include/phpmailer/language/phpmailer.lang-nl.php b/include/phpmailer/language/phpmailer.lang-nl.php index f637fd82..d2c380b0 100644 --- a/include/phpmailer/language/phpmailer.lang-nl.php +++ b/include/phpmailer/language/phpmailer.lang-nl.php @@ -1,58 +1,25 @@ \ No newline at end of file diff --git a/include/phpmailer/language/phpmailer.lang-no.php b/include/phpmailer/language/phpmailer.lang-no.php index faf6beb1..65cb8843 100644 --- a/include/phpmailer/language/phpmailer.lang-no.php +++ b/include/phpmailer/language/phpmailer.lang-no.php @@ -1,58 +1,25 @@ \ No newline at end of file diff --git a/include/phpmailer/language/phpmailer.lang-pl.php b/include/phpmailer/language/phpmailer.lang-pl.php index 52341cb7..f4fd801d 100644 --- a/include/phpmailer/language/phpmailer.lang-pl.php +++ b/include/phpmailer/language/phpmailer.lang-pl.php @@ -1,56 +1,25 @@ \ No newline at end of file diff --git a/include/phpmailer/language/phpmailer.lang-ro.php b/include/phpmailer/language/phpmailer.lang-ro.php index 6d512bae..f6aa9225 100644 --- a/include/phpmailer/language/phpmailer.lang-ro.php +++ b/include/phpmailer/language/phpmailer.lang-ro.php @@ -1,55 +1,27 @@ */ - -$PHPMAILER_LANG = array(); - -$PHPMAILER_LANG["provide_address"] = 'Trebuie sa adaugati cel putin un recipient (adresa de mail).'; -$PHPMAILER_LANG["mailer_not_supported"] = ' mailer nu este suportat.'; -$PHPMAILER_LANG["execute"] = 'Nu pot executa: '; -$PHPMAILER_LANG["instantiate"] = 'Nu am putut instantia functia mail.'; -$PHPMAILER_LANG["authenticate"] = 'Eroare SMTP: Nu a functionat autentificarea.'; -$PHPMAILER_LANG["from_failed"] = 'Urmatoarele adrese From au dat eroare: '; -$PHPMAILER_LANG["recipients_failed"] = 'Eroare SMTP: Urmatoarele adrese de mail au dat eroare: '; -$PHPMAILER_LANG["data_not_accepted"] = 'Eroare SMTP: Continutul mailului nu a fost acceptat.'; -$PHPMAILER_LANG["connect_host"] = 'Eroare SMTP: Nu m-am putut conecta la adresa SMTP.'; -$PHPMAILER_LANG["file_access"] = 'Nu pot accesa fisierul: '; -$PHPMAILER_LANG["file_open"] = 'Eroare de fisier: Nu pot deschide fisierul: '; -$PHPMAILER_LANG["encoding"] = 'Encodare necunoscuta: '; -$PHPMAILER_LANG["signing"] = 'Signing Error: '; +* PHPMailer language file: refer to English translation for definitive list +* Romanian Version +* @package PHPMailer +* @author Catalin Constantin +*/ +$PHPMAILER_LANG['authenticate'] = 'Eroare SMTP: Nu a functionat autentificarea.'; +$PHPMAILER_LANG['connect_host'] = 'Eroare SMTP: Nu m-am putut conecta la adresa SMTP.'; +$PHPMAILER_LANG['data_not_accepted'] = 'Eroare SMTP: Continutul mailului nu a fost acceptat.'; +//$PHPMAILER_LANG['empty_message'] = 'Message body empty'; +$PHPMAILER_LANG['encoding'] = 'Encodare necunoscuta: '; +$PHPMAILER_LANG['execute'] = 'Nu pot executa: '; +$PHPMAILER_LANG['file_access'] = 'Nu pot accesa fisierul: '; +$PHPMAILER_LANG['file_open'] = 'Eroare de fisier: Nu pot deschide fisierul: '; +$PHPMAILER_LANG['from_failed'] = 'Urmatoarele adrese From au dat eroare: '; +$PHPMAILER_LANG['instantiate'] = 'Nu am putut instantia functia mail.'; +//$PHPMAILER_LANG['invalid_email'] = 'Not sending, email address is invalid: '; +$PHPMAILER_LANG['mailer_not_supported'] = ' mailer nu este suportat.'; +$PHPMAILER_LANG['provide_address'] = 'Trebuie sa adaugati cel putin un recipient (adresa de mail).'; +$PHPMAILER_LANG['recipients_failed'] = 'Eroare SMTP: Urmatoarele adrese de mail au dat eroare: '; +//$PHPMAILER_LANG['signing'] = 'Signing Error: '; +//$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.'; +//$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: '; +//$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: '; ?> \ No newline at end of file diff --git a/include/phpmailer/language/phpmailer.lang-ru.php b/include/phpmailer/language/phpmailer.lang-ru.php index f8b3ee23..d6990525 100644 --- a/include/phpmailer/language/phpmailer.lang-ru.php +++ b/include/phpmailer/language/phpmailer.lang-ru.php @@ -1,55 +1,25 @@ */ - -$PHPMAILER_LANG = array(); - -$PHPMAILER_LANG["provide_address"] = 'Ïîæàëóéñòà, ââåäèòå õîòÿ áû îäèí àäðåñ e-mail ' . - 'ïîëó÷àòåëÿ.'; -$PHPMAILER_LANG["mailer_not_supported"] = ' - ïî÷òîâûé ñåðâåð íå ïîääåðæèâàåòñÿ.'; -$PHPMAILER_LANG["execute"] = 'Íåâîçìîæíî âûïîëíèòü êîìàíäó: '; -$PHPMAILER_LANG["instantiate"] = 'Íåâîçìîæíî çàïóñòèòü ôóíêöèþ mail.'; -$PHPMAILER_LANG["authenticate"] = 'Îøèáêà SMTP: îøèáêà àâòîðèçàöèè.'; -$PHPMAILER_LANG["from_failed"] = 'Íåâåðíûé àäðåñ îòïðàâèòåëÿ: '; -$PHPMAILER_LANG["recipients_failed"] = 'Îøèáêà SMTP: îòïðàâêà ïî ñëåäóþùèì ' . - 'àäðåñàì ïîëó÷àòåëåé íå óäàëàñü: '; -$PHPMAILER_LANG["data_not_accepted"] = 'Îøèáêà SMTP: äàííûå íå ïðèíÿòû.'; -$PHPMAILER_LANG["connect_host"] = 'Îøèáêà SMTP: íå óäàåòñÿ ïîäêëþ÷èòüñÿ ê ñåðâåðó SMTP.'; -$PHPMAILER_LANG["file_access"] = 'Íåò äîñòóïà ê ôàéëó: '; -$PHPMAILER_LANG["file_open"] = 'Ôàéëîâàÿ îøèáêà: íå óäàåòñÿ îòêðûòü ôàéë: '; -$PHPMAILER_LANG["encoding"] = 'Íåèçâåñòíûé âèä êîäèðîâêè: '; -$PHPMAILER_LANG["signing"] = 'Signing Error: '; +* PHPMailer language file: refer to English translation for definitive list +* Russian Version by Alexey Chumakov +*/ +$PHPMAILER_LANG['authenticate'] = 'Ошибка SMTP: ошибка авторизации.'; +$PHPMAILER_LANG['connect_host'] = 'Ошибка SMTP: не удается подключиться к серверу SMTP.'; +$PHPMAILER_LANG['data_not_accepted'] = 'Ошибка SMTP: данные не приняты.'; +//$PHPMAILER_LANG['empty_message'] = 'Message body empty'; +$PHPMAILER_LANG['encoding'] = 'Неизвестный вид кодировки: '; +$PHPMAILER_LANG['execute'] = 'Невозможно выполнить команду: '; +$PHPMAILER_LANG['file_access'] = 'Нет доступа к файлу: '; +$PHPMAILER_LANG['file_open'] = 'Файловая ошибка: не удается открыть файл: '; +$PHPMAILER_LANG['from_failed'] = 'Неверный адрес отправителя: '; +$PHPMAILER_LANG['instantiate'] = 'Невозможно запустить функцию mail.'; +//$PHPMAILER_LANG['invalid_email'] = 'Not sending, email address is invalid: '; +$PHPMAILER_LANG['provide_address'] = 'Пожалуйста, введите хотя бы один адрес e-mail получателя.'; +$PHPMAILER_LANG['mailer_not_supported'] = ' - почтовый сервер не поддерживается.'; +$PHPMAILER_LANG['recipients_failed'] = 'Ошибка SMTP: отправка по следующим адресам получателей не удалась: '; +//$PHPMAILER_LANG['signing'] = 'Signing Error: '; +//$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.'; +//$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: '; +//$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: '; ?> \ No newline at end of file diff --git a/include/phpmailer/language/phpmailer.lang-se.php b/include/phpmailer/language/phpmailer.lang-se.php index 5de32bbe..67e05f59 100644 --- a/include/phpmailer/language/phpmailer.lang-se.php +++ b/include/phpmailer/language/phpmailer.lang-se.php @@ -1,58 +1,26 @@ */ - -$PHPMAILER_LANG = array(); - -$PHPMAILER_LANG["provide_address"] = 'Du måste ange minst en ' . - 'mottagares e-postadress.'; -$PHPMAILER_LANG["mailer_not_supported"] = ' mailer stöds inte.'; -$PHPMAILER_LANG["execute"] = 'Kunde inte köra: '; -$PHPMAILER_LANG["instantiate"] = 'Kunde inte initiera e-postfunktion.'; -$PHPMAILER_LANG["authenticate"] = 'SMTP fel: Kunde inte autentisera.'; -$PHPMAILER_LANG["from_failed"] = 'Följande avsändaradress är felaktig: '; -$PHPMAILER_LANG["recipients_failed"] = 'SMTP fel: Följande ' . - 'mottagare är felaktig: '; -$PHPMAILER_LANG["data_not_accepted"] = 'SMTP fel: Data accepterades inte.'; -$PHPMAILER_LANG["connect_host"] = 'SMTP fel: Kunde inte ansluta till SMTP-server.'; -$PHPMAILER_LANG["file_access"] = 'Ingen åtkomst till fil: '; -$PHPMAILER_LANG["file_open"] = 'Fil fel: Kunde inte öppna fil: '; -$PHPMAILER_LANG["encoding"] = 'Okänt encode-format: '; -$PHPMAILER_LANG["signing"] = 'Signing Error: '; +* PHPMailer language file: refer to English translation for definitive list +* Swedish Version +* Author: Johan Linnér +*/ +$PHPMAILER_LANG['authenticate'] = 'SMTP fel: Kunde inte autentisera.'; +$PHPMAILER_LANG['connect_host'] = 'SMTP fel: Kunde inte ansluta till SMTP-server.'; +$PHPMAILER_LANG['data_not_accepted'] = 'SMTP fel: Data accepterades inte.'; +//$PHPMAILER_LANG['empty_message'] = 'Message body empty'; +$PHPMAILER_LANG['encoding'] = 'Okänt encode-format: '; +$PHPMAILER_LANG['execute'] = 'Kunde inte köra: '; +$PHPMAILER_LANG['file_access'] = 'Ingen Ã¥tkomst till fil: '; +$PHPMAILER_LANG['file_open'] = 'Fil fel: Kunde inte öppna fil: '; +$PHPMAILER_LANG['from_failed'] = 'Följande avsändaradress är felaktig: '; +$PHPMAILER_LANG['instantiate'] = 'Kunde inte initiera e-postfunktion.'; +//$PHPMAILER_LANG['invalid_email'] = 'Not sending, email address is invalid: '; +$PHPMAILER_LANG['provide_address'] = 'Du mÃ¥ste ange minst en mottagares e-postadress.'; +$PHPMAILER_LANG['mailer_not_supported'] = ' mailer stöds inte.'; +$PHPMAILER_LANG['recipients_failed'] = 'SMTP fel: Följande mottagare är felaktig: '; +//$PHPMAILER_LANG['signing'] = 'Signing Error: '; +//$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.'; +//$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: '; +//$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: '; ?> \ No newline at end of file diff --git a/include/phpmailer/language/phpmailer.lang-tr.php b/include/phpmailer/language/phpmailer.lang-tr.php index 88aa1028..d24627a4 100644 --- a/include/phpmailer/language/phpmailer.lang-tr.php +++ b/include/phpmailer/language/phpmailer.lang-tr.php @@ -1,61 +1,27 @@ \ No newline at end of file diff --git a/include/phpmailer/language/phpmailer.lang-zh.php b/include/phpmailer/language/phpmailer.lang-zh.php new file mode 100644 index 00000000..fef66f8c --- /dev/null +++ b/include/phpmailer/language/phpmailer.lang-zh.php @@ -0,0 +1,26 @@ + +*/ + +$PHPMAILER_LANG['authenticate'] = 'SMTP 錯誤:登錄失敗。'; +$PHPMAILER_LANG['connect_host'] = 'SMTP 錯誤:無法連接到 SMTP 主機。'; +$PHPMAILER_LANG['data_not_accepted'] = 'SMTP 錯誤:數據不被接受。'; +//$PHPMAILER_LANG['empty_message'] = 'Message body empty'; +$PHPMAILER_LANG['encoding'] = '未知編碼: '; +$PHPMAILER_LANG['file_access'] = '無法訪問文件:'; +$PHPMAILER_LANG['file_open'] = '文件錯誤:無法打開文件:'; +$PHPMAILER_LANG['from_failed'] = '發送地址錯誤:'; +$PHPMAILER_LANG['execute'] = '無法執行:'; +$PHPMAILER_LANG['instantiate'] = '未知函數調用。'; +//$PHPMAILER_LANG['invalid_email'] = 'Not sending, email address is invalid: '; +$PHPMAILER_LANG['provide_address'] = '必須提供至少一個收件人地址。'; +$PHPMAILER_LANG['mailer_not_supported'] = '發信客戶端不被支持。'; +$PHPMAILER_LANG['recipients_failed'] = 'SMTP 錯誤:收件人地址錯誤:'; +//$PHPMAILER_LANG['signing'] = 'Signing Error: '; +//$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.'; +//$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: '; +//$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: '; +?> \ No newline at end of file diff --git a/include/phpmailer/language/phpmailer.lang-zh_cn.php b/include/phpmailer/language/phpmailer.lang-zh_cn.php new file mode 100644 index 00000000..b1884043 --- /dev/null +++ b/include/phpmailer/language/phpmailer.lang-zh_cn.php @@ -0,0 +1,26 @@ + +*/ + +$PHPMAILER_LANG['authenticate'] = 'SMTP 错误:登录失败。'; +$PHPMAILER_LANG['connect_host'] = 'SMTP 错误:无法连接到 SMTP 主机。'; +$PHPMAILER_LANG['data_not_accepted'] = 'SMTP 错误:数据不被接受。'; +//$P$PHPMAILER_LANG['empty_message'] = 'Message body empty'; +$PHPMAILER_LANG['encoding'] = '未知编码: '; +$PHPMAILER_LANG['execute'] = '无法执行:'; +$PHPMAILER_LANG['file_access'] = '无法访问文件:'; +$PHPMAILER_LANG['file_open'] = '文件错误:无法打开文件:'; +$PHPMAILER_LANG['from_failed'] = '发送地址错误:'; +$PHPMAILER_LANG['instantiate'] = '未知函数调用。'; +//$PHPMAILER_LANG['invalid_email'] = 'Not sending, email address is invalid: '; +$PHPMAILER_LANG['mailer_not_supported'] = '发信客户端不被支持。'; +$PHPMAILER_LANG['provide_address'] = '必须提供至少一个收件人地址。'; +$PHPMAILER_LANG['recipients_failed'] = 'SMTP 错误:收件人地址错误:'; +//$PHPMAILER_LANG['signing'] = 'Signing Error: '; +//$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.'; +//$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: '; +//$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: '; +?> \ No newline at end of file diff --git a/include/utils.php b/include/utils.php index 10370f14..78570c7d 100644 --- a/include/utils.php +++ b/include/utils.php @@ -4874,3 +4874,24 @@ function getReportNameTranslation($reportName) { return $title; } + +/** + * Remove vars marked senstitive from array + * @param array $defs + * @param SugarBean|array $data + * @return mixed $data without sensitive fields + */ +function clean_sensitive_data($defs, $data) +{ + foreach($defs as $field => $def) { + if(!empty($def['sensitive'])) { + if(is_array($data)) { + $data[$field] = ''; + } + if($data instanceof SugarBean) { + $data->$field = ''; + } + } + } + return $data; +} \ No newline at end of file diff --git a/include/utils/layout_utils.php b/include/utils/layout_utils.php index aea6c64a..156c3a0b 100644 --- a/include/utils/layout_utils.php +++ b/include/utils/layout_utils.php @@ -84,8 +84,7 @@ EOHTML; -$other_text - +$other_text EOHTML; if ($show_help) { $the_form .= ""; diff --git a/install/language/en_us.lang.php b/install/language/en_us.lang.php index 392bd128..170a97ee 100644 --- a/install/language/en_us.lang.php +++ b/install/language/en_us.lang.php @@ -92,7 +92,7 @@ $mod_strings = array( 'ERR_CHECKSYS_CONFIG_NOT_WRITABLE' => 'The config file exists but is not writeable. Please take the necessary steps to make the file writeable. Depending on your Operating system, this might require you to change the permissions by running chmod 766, or to right click on the filename to access the properties and uncheck the read only option.', 'ERR_CHECKSYS_CONFIG_OVERRIDE_NOT_WRITABLE' => 'The config override file exists but is not writeable. Please take the necessary steps to make the file writeable. Depending on your Operating system, this might require you to change the permissions by running chmod 766, or to right click on the filename to access the properties and uncheck the read only option.', 'ERR_CHECKSYS_CUSTOM_NOT_WRITABLE' => 'The Custom Directory exists but is not writeable. You may have to change permissions on it (chmod 766) or right click on it and uncheck the read only option, depending on your Operating System. Please take the needed steps to make the file writeable.', - 'ERR_CHECKSYS_FILES_NOT_WRITABLE' => "The files or directories listed below are not writeable or are missing and cannot be created. Depending on your Operating System, correcting this may require you to change permissions on the files or parent directory (chmod 766), or to right click on the parent directory and uncheck the 'read only' option and apply it to all subfolders.", + 'ERR_CHECKSYS_FILES_NOT_WRITABLE' => "The files or directories listed below are not writeable or are missing and cannot be created. Depending on your Operating System, correcting this may require you to change permissions on the files or parent directory (chmod 755), or to right click on the parent directory and uncheck the 'read only' option and apply it to all subfolders.", //'ERR_CHECKSYS_SAFE_MODE' => 'Safe Mode is On (please disable in php.ini)', 'ERR_CHECKSYS_SAFE_MODE' => 'Safe Mode is On (you may wish to disable in php.ini)', 'ERR_CHECKSYS_ZLIB' => 'ZLib support not found: SugarCRM reaps enormous performance benefits with zlib compression.', diff --git a/json_server.php b/json_server.php index b639db4b..f5afdafc 100644 --- a/json_server.php +++ b/json_server.php @@ -142,6 +142,9 @@ function json_query($request_id, $params) { $list_arr[$i]['module']= $list_return[$i]->object_name; foreach($args['field_list'] as $field) { + if(!empty($list_return[$i]->field_name_map[$field]['sensitive'])) { + continue; + } // handle enums if( (isset($list_return[$i]->field_name_map[$field]['type']) && $list_return[$i]->field_name_map[$field]['type'] == 'enum') || (isset($list_return[$i]->field_name_map[$field]['custom_type']) && $list_return[$i]->field_name_map[$field]['custom_type'] == 'enum')) { @@ -236,7 +239,8 @@ function authenticate() { return $result; } -function construct_where(&$query_obj, $table='',$module=null) { +function construct_where(&$query_obj, $table='',$module=null) +{ if(! empty($table)) { $table .= "."; } @@ -247,7 +251,9 @@ function construct_where(&$query_obj, $table='',$module=null) { } foreach($query_obj['conditions'] as $condition) { - + if($condition['name'] == 'user_hash') { + continue; + } if ($condition['name']=='email1' or $condition['name']=='email2') { $email1_value=strtoupper($condition['value']); @@ -276,8 +282,12 @@ function construct_where(&$query_obj, $table='',$module=null) { if($table == 'users.') { $cond_arr[] = $table."status='Active'"; } + $group = strtolower(trim($query_obj['group'])); + if($group != "and" && $group != "or") { + $group = "and"; + } - return implode(" {$query_obj['group']} ",$cond_arr); + return implode(" $group ",$cond_arr); } //// END UTILS diff --git a/jssource/JSGroupings.php b/jssource/JSGroupings.php index d50bf655..ed39d7b0 100644 --- a/jssource/JSGroupings.php +++ b/jssource/JSGroupings.php @@ -59,6 +59,7 @@ 'include/javascript/phpjs/get_html_translation_table.js' => 'include/javascript/sugar_grp1.js', 'include/javascript/phpjs/html_entity_decode.js' => 'include/javascript/sugar_grp1.js', 'include/javascript/phpjs/htmlentities.js' => 'include/javascript/sugar_grp1.js', + 'include/EditView/Panels.js' => 'include/javascript/sugar_grp1.js', ), //jquery libraries $sugar_grp_jquery = array( @@ -190,6 +191,6 @@ /** * Check for custom additions to this code */ - if(file_exists("custom/jssource/JSGroupings.php")) { - require("custom/jssource/JSGroupings.php"); + if(file_exists("custom/application/Ext/JSGroupings/jsgroups.ext.php")) { + require("custom/application/Ext/JSGroupings/jsgroups.ext.php"); } diff --git a/jssource/src_files/include/EditView/Panels.js b/jssource/src_files/include/EditView/Panels.js new file mode 100644 index 00000000..85031448 --- /dev/null +++ b/jssource/src_files/include/EditView/Panels.js @@ -0,0 +1,66 @@ +/********************************************************************************* + * SugarCRM Community Edition is a customer relationship management program developed by + * SugarCRM, Inc. Copyright (C) 2004-2012 SugarCRM Inc. + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU Affero General Public License version 3 as published by the + * Free Software Foundation with the addition of the following permission added + * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK + * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY + * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more + * details. + * + * You should have received a copy of the GNU Affero General Public License along with + * this program; if not, see http://www.gnu.org/licenses or write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA. + * + * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road, + * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com. + * + * The interactive user interfaces in modified source and object code versions + * of this program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU Affero General Public License version 3. + * + * In accordance with Section 7(b) of the GNU Affero General Public License version 3, + * these Appropriate Legal Notices must retain the display of the "Powered by + * SugarCRM" logo. If the display of the logo is not reasonably feasible for + * technical reasons, the Appropriate Legal Notices must display the words + * "Powered by SugarCRM". + ********************************************************************************/ + + +function initPanel(id, state) { + panelId = 'detailpanel_' + id; + expandPanel(id); + if(state == 'collapsed') { + collapsePanel(id); + } +} + +function expandPanel(id) { + var panelId = 'detailpanel_' + id; + document.getElementById(panelId).className = document.getElementById(panelId).className.replace(/(expanded|collapsed)/ig, '') + ' expanded'; +} + +function collapsePanel(id) { + var panelId = 'detailpanel_' + id; + document.getElementById(panelId).className = document.getElementById(panelId).className.replace(/(expanded|collapsed)/ig, '') + ' collapsed'; +} + +function setCollapseState(mod, panel, isCollapsed) { + var sugar_panel_collase = Get_Cookie("sugar_panel_collase"); + if(sugar_panel_collase == null) { + sugar_panel_collase = {}; + } else { + sugar_panel_collase = YAHOO.lang.JSON.parse(sugar_panel_collase); + } + sugar_panel_collase[mod] = sugar_panel_collase[mod] || {}; + sugar_panel_collase[mod][panel] = isCollapsed; + + Set_Cookie('sugar_panel_collase', YAHOO.lang.JSON.stringify(sugar_panel_collase),30,'/','',''); +} \ No newline at end of file diff --git a/jssource/src_files/include/javascript/jsclass_async.js b/jssource/src_files/include/javascript/jsclass_async.js index 8ddcb162..962f98cf 100644 --- a/jssource/src_files/include/javascript/jsclass_async.js +++ b/jssource/src_files/include/javascript/jsclass_async.js @@ -82,14 +82,8 @@ SugarVCalClient.prototype.init = function() {} SugarVCalClient.prototype.load = function(user_id, request_id) { this.user_id = user_id; - var vcal_server = './vcal_server.php?type=vfb&source=outlook&user_id=' + user_id; - if (typeof(window.combo_date_start) != 'undefined') { - var date_start = window.combo_date_start.datetime; - vcal_server += '&datestart='+date_start; - } - // Bug 44239: Removed reliance on jsolait - YAHOO.util.Connect.asyncRequest('GET', vcal_server, { + YAHOO.util.Connect.asyncRequest('GET', './vcal_server.php?type=vfb&source=outlook&user_id=' + user_id, { success: function (result) { if (typeof GLOBAL_REGISTRY.freebusy == 'undefined') { GLOBAL_REGISTRY.freebusy = new Object(); diff --git a/jssource/src_files/include/javascript/sugar_3.js b/jssource/src_files/include/javascript/sugar_3.js index 5c82c3f4..e72f69ff 100644 --- a/jssource/src_files/include/javascript/sugar_3.js +++ b/jssource/src_files/include/javascript/sugar_3.js @@ -72,6 +72,7 @@ if (typeof(SUGAR) == "undefined") { // Namespaces SUGAR.namespace("themes"); +SUGAR.namespace("tour"); /** * Namespace for Homepage diff --git a/jssource/src_files/include/javascript/tour.js b/jssource/src_files/include/javascript/tour.js new file mode 100644 index 00000000..87e8d586 --- /dev/null +++ b/jssource/src_files/include/javascript/tour.js @@ -0,0 +1,241 @@ +/********************************************************************************* + * SugarCRM Community Edition is a customer relationship management program developed by + * SugarCRM, Inc. Copyright (C) 2004-2012 SugarCRM Inc. + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU Affero General Public License version 3 as published by the + * Free Software Foundation with the addition of the following permission added + * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK + * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY + * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more + * details. + * + * You should have received a copy of the GNU Affero General Public License along with + * this program; if not, see http://www.gnu.org/licenses or write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA. + * + * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road, + * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com. + * + * The interactive user interfaces in modified source and object code versions + * of this program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU Affero General Public License version 3. + * + * In accordance with Section 7(b) of the GNU Affero General Public License version 3, + * these Appropriate Legal Notices must retain the display of the "Powered by + * SugarCRM" logo. If the display of the logo is not reasonably feasible for + * technical reasons, the Appropriate Legal Notices must display the words + * "Powered by SugarCRM". + ********************************************************************************/ + + + +SUGAR.tour = function() { +var tourModal; + return { + init: function(params) { + var modals = params.modals; + + tourModal = $('').modal({backdrop: false}).draggable({handle: ".modal-header"}); + + var tourIdSel = "#"+params.id; + + $.ajax({ + url: params.modalUrl, + success: function(data){ + $(tourIdSel).html(data); + + $(tourIdSel+'Start a.btn.btn-primary').on("click",function(e){ + $(tourIdSel+'Start').css("display","none"); + $(tourIdSel+'End').css("display","block"); + tourModal.modal("hide"); + modalArray[0].modal('show'); + $(modals[0].target).popoverext('show'); + }); + $(tourIdSel+'Start a.btn').not('.btn-primary').on("click",function(e){ + $(tourIdSel+'Start').css("display","none"); + $(tourIdSel+'End').css("display","block"); + centerModal(); + }); + $(tourIdSel+' a.close').on("click",function(e){ + tourModal.modal("hide"); + SUGAR.tour.saveUserPref(params.prefUrl); + params.onTourFinish(); + }); + $(tourIdSel+'End a.btn.btn-primary').on("click",function(e){ + tourModal.modal("hide"); + SUGAR.tour.saveUserPref(params.prefUrl); + params.onTourFinish(); + }); + + centerModal(); + + $('
    arrow
    '); + var modalArray = new Array(); + + for(var i=0; i').modal({backdrop: false}).draggable({handle: ".modal-header"}); +// modalArray[i].modal('show'); + var modalContent = "
    ×

    "+modals[i].title+"

    "; + + modalContent += "
    "+modals[i].content+"
    " ; + + modalContent += footerTemplate(i,modals); + $('#'+modalId).html(modalContent); + modalArray[i].modal("hide"); + + + $(modals[i].target).ready(function(){ + + var direction,bounce; + if (modals[i].placement == "top right") { + bounce = "up right"; + direction = "down right" + } else if (modals[i].placement == "top left") { + bounce = "up left"; + direction = "down left" + } else if(modals[i].placement == "top") { + bounce = "up"; + direction = "down" + } else if (modals[i].placement == "bottom right") { + bounce = "down right"; + direction = "up right" + } else if (modals[i].placement == "bottom left") { + bounce = "down left"; + direction = "up left" + } else { + bounce = "down"; + direction = "right" + } + + $(modals[i].target).popoverext({ + title: "", + content: "arrow", + footer: "", + placement: modals[i].placement, + id: true, + fixed: true, + trigger: 'manual', + template: '
    ', + onShow: function(){ + $('.pointer').css('top','0px'); + + $(".popover .pointer") + .effect("custombounce", { times:1000, direction: bounce, distance: 50, gravity: false }, 2000, + function(){ + +// $('.pointer').attr('style',''); + + } + ); + }, + leftOffset: modals[i].leftOffset ? modals[i].leftOffset : 0, + topOffset: modals[i].topOffset ? modals[i].topOffset : 0, + hideOnBlur: true + + }); + }); + //empty popover div and insert arrow + $(modals[i].target+"Popover").empty().html("arrow"); + + } + + $(window).resize(function() { + centerModal(); + }); + function centerModal() { + $(tourIdSel).css("left",$(window).width()/2 - $(tourIdSel).width()/2); + $(tourIdSel).css("margin-top",-$(tourIdSel).height()/2); + } + + function nextModal (i) { + + + if(modals.length - 1 != i) { + $(modals[i].target).popoverext('hide'); + $(modals[i+1].target).popoverext('show'); + modalArray[i].modal('hide'); + modalArray[i+1].modal('show'); + } else { + $(modals[i].target).popoverext('hide'); + modalArray[i].modal('hide'); + tourModal.modal("show"); + centerModal(); + } + + } + + function prevModal (i){ + + $(modals[i].target).popoverext('hide'); + $(modals[i-1].target).popoverext('show'); + modalArray[i].modal('hide'); + modalArray[i-1].modal('show'); + } + + + function skipTour (i) { + $(modals[i].target).popoverext('hide'); + modalArray[i].modal('hide'); + tourModal.modal("show"); + centerModal(); + } + + function footerTemplate (i,modals) { + var content = $('
    ') + var footer = $("
    "); + + var skip = $(""+SUGAR.language.get('app_strings', 'LBL_TOUR_SKIP')+""); + var next = $(''+SUGAR.language.get('app_strings', 'LBL_TOUR_NEXT')+' '); + content.append(footer); + footer.append(skip).append(next); + + var back = $(''+SUGAR.language.get('app_strings', 'LBL_TOUR_BACK')+''); + + + $('#nextModal'+i).live("click", function(){ + nextModal(i); + }); + + $('#prevModal'+i).live("click", function(){ + prevModal(i); + }); + + $('#skipTour').live("click", function(){ + skipTour(i); + }); + + + + if(i != 0) { + footer.append(back); + } + + return content.html(); + } + + + + + + } + }); + }, + saveUserPref: function(url) { + $.ajax({ + type: "GET", + url: url + }); + } + + + + + }; +}(); diff --git a/jssource/src_files/modules/Home/tour.js b/jssource/src_files/modules/Home/tour.js new file mode 100644 index 00000000..396d98dd --- /dev/null +++ b/jssource/src_files/modules/Home/tour.js @@ -0,0 +1,125 @@ +/********************************************************************************* + * SugarCRM Community Edition is a customer relationship management program developed by + * SugarCRM, Inc. Copyright (C) 2004-2012 SugarCRM Inc. + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU Affero General Public License version 3 as published by the + * Free Software Foundation with the addition of the following permission added + * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK + * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY + * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more + * details. + * + * You should have received a copy of the GNU Affero General Public License along with + * this program; if not, see http://www.gnu.org/licenses or write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA. + * + * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road, + * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com. + * + * The interactive user interfaces in modified source and object code versions + * of this program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU Affero General Public License version 3. + * + * In accordance with Section 7(b) of the GNU Affero General Public License version 3, + * these Appropriate Legal Notices must retain the display of the "Powered by + * SugarCRM" logo. If the display of the logo is not reasonably feasible for + * technical reasons, the Appropriate Legal Notices must display the words + * "Powered by SugarCRM". + ********************************************************************************/ + + +var rtl = rtl == "undefined" ? false : rtl; +var modals=new Array(); +modals[0] = { + target: "#moduleTab_AllHome", + title: SUGAR.language.get('Home', 'LBL_TOUR_HOME'), + content: SUGAR.language.get('Home', 'LBL_TOUR_HOME_DESCRIPTION'), + placement: "bottom" +}; +modals[1] = { + target: "#moduleTab_AllAccounts", + title: SUGAR.language.get('Home', 'LBL_TOUR_MODULES'), + content: SUGAR.language.get('Home', 'LBL_TOUR_MODULES_DESCRIPTION'), + placement: "bottom" +}; +modals[2] = { + target: "#moduleTabExtraMenuAll", + title: SUGAR.language.get('Home', 'LBL_TOUR_MORE'), + content: SUGAR.language.get('Home', 'LBL_TOUR_MORE_DESCRIPTION'), + placement: "bottom" +}; +modals[3] = { + target: "#dcmenuSearchDiv", + title: SUGAR.language.get('Home', 'LBL_TOUR_SEARCH'), + content: SUGAR.language.get('Home', 'LBL_TOUR_SEARCH_DESCRIPTION'), + placement: "bottom" +}; +modals[4] = { + target: $("#dcmenuSugarCube").length == 0 ? "#dcmenuSugarCubeEmpty" : "#dcmenuSugarCube", + title: SUGAR.language.get('Home', 'LBL_TOUR_NOTIFICATIONS'), + content: SUGAR.language.get('Home', 'LBL_TOUR_NOTIFICATIONS_DESCRIPTION'), + placement: "bottom" +}; +modals[5] = { + target: "#globalLinksModule", + title: SUGAR.language.get('Home', 'LBL_TOUR_PROFILE'), + content: SUGAR.language.get('Home', 'LBL_TOUR_PROFILE_DESCRIPTION'), + placement: "bottom" +}; +modals[6] = { + target: "#quickCreate", + title: SUGAR.language.get('Home', 'LBL_TOUR_QUICKCREATE'), + content: SUGAR.language.get('Home', 'LBL_TOUR_QUICKCREATE_DESCRIPTION'), + placement: "bottom right", + leftOffset: rtl ? -40 : 40, + topOffset: -10 +}; +modals[7] = { + target: "#arrow", + title: SUGAR.language.get('Home', 'LBL_TOUR_FOOTER'), + content: SUGAR.language.get('Home', 'LBL_TOUR_FOOTER_DESCRIPTION'), + placement: "top right", + leftOffset: rtl ? -90 : 80, + topOffset: -40 +}; +modals[8] = { + target: "#integrations", + title: SUGAR.language.get('Home', 'LBL_TOUR_CUSTOM'), + content: SUGAR.language.get('Home', 'LBL_TOUR_CUSTOM_DESCRIPTION'), + placement: "top", + leftOffset: rtl ? 30 : -30 +}; +modals[9] = { + target: "#logo", + title: SUGAR.language.get('Home', 'LBL_TOUR_BRAND'), + content: SUGAR.language.get('Home', 'LBL_TOUR_BRAND_DESCRIPTION'), + placement: "top" +}; + + + +$(document).ready(function() { + SUGAR.tour.init({ + id: 'tour', + modals: modals, + modalUrl: "index.php?module=Home&action=tour&to_pdf=1", + prefUrl: "index.php?module=Users&action=UpdateTourStatus&to_pdf=true&viewed=true", + className: 'whatsnew', + onTourFinish: function() { + $('#bootstrapJs').remove(); + $('#popoverext').remove(); + $('#bounce').remove(); + $('#bootstrapCss').remove(); + $('#tourCss').remove(); + $('#tourJs').remove(); + $('#whatsNewsJs').remove(); + } + }); +}); + \ No newline at end of file diff --git a/modules/Administration/language/en_us.lang.php b/modules/Administration/language/en_us.lang.php index 8f9c1551..77ab1698 100644 --- a/modules/Administration/language/en_us.lang.php +++ b/modules/Administration/language/en_us.lang.php @@ -361,6 +361,7 @@ $mod_strings = array ( 'LBL_LICENSE_VALIDATION_KEY' => 'Validation Key', 'LBL_LICENSE_VALIDATION' => 'License Validation', 'LBL_LICENSE' => 'License', + 'LBL_LICENSE_UNAUTHORIZED_ACCESS' => 'Unauthorized access to license settings.', 'LBL_LIST_FIRST_CONNECT_DATE' => 'First Connect Date', 'LBL_LIST_LAST_CONNECT_DATE' => 'Last Connect Date', 'LBL_LIST_NUM_SYNCS' => 'Num. of Syncs', diff --git a/modules/Administration/metadata/adminpaneldefs.php b/modules/Administration/metadata/adminpaneldefs.php index 1f39344b..80040645 100644 --- a/modules/Administration/metadata/adminpaneldefs.php +++ b/modules/Administration/metadata/adminpaneldefs.php @@ -42,6 +42,10 @@ $admin_option_defs['Users']['user_management']= array('Users','LBL_MANAGE_USERS_ $admin_option_defs['Users']['roles_management']= array('Roles','LBL_MANAGE_ROLES_TITLE','LBL_MANAGE_ROLES','./index.php?module=ACLRoles&action=index'); $admin_option_defs['Administration']['password_management']= array('Password','LBL_MANAGE_PASSWORD_TITLE','LBL_MANAGE_PASSWORD','./index.php?module=Administration&action=PasswordManager'); $admin_group_header[]= array('LBL_USERS_TITLE','',false,$admin_option_defs, 'LBL_USERS_DESC'); +$license_management = false; + if (!isset($GLOBALS['sugar_config']['hide_admin_licensing']) || !$GLOBALS['sugar_config']['hide_admin_licensing']) { + $license_management = array('License','LBL_MANAGE_LICENSE_TITLE','LBL_MANAGE_LICENSE','./index.php?module=Administration&action=LicenseSettings'); + } //Sugar Connect diff --git a/modules/Calls/Call.php b/modules/Calls/Call.php index 92802283..b26a1861 100644 --- a/modules/Calls/Call.php +++ b/modules/Calls/Call.php @@ -128,8 +128,8 @@ class Call extends SugarBean { $this->field_name_map[$field['name']] = $field; } - - + + if(!empty($GLOBALS['app_list_strings']['duration_intervals'])) $this->minutes_values = $GLOBALS['app_list_strings']['duration_intervals']; @@ -161,15 +161,15 @@ class Call extends SugarBean { function save($check_notify = FALSE) { global $timedate,$current_user; - if(isset($this->date_start) && isset($this->duration_hours) && isset($this->duration_minutes)) + if(isset($this->date_start) && isset($this->duration_hours) && isset($this->duration_minutes)) { $td = $timedate->fromDb($this->date_start); if($td) { $this->date_end = $td->modify("+{$this->duration_hours} hours {$this->duration_minutes} mins")->asDb(); - } + } } - + if(!empty($_REQUEST['send_invites']) && $_REQUEST['send_invites'] == '1') { $check_notify = true; } else { @@ -463,8 +463,10 @@ class Call extends SugarBean { if (!empty($this->contact_id)) { // Bug# 46125 - make first name, last name, salutation and title of Contacts respect field level ACLs $contact_temp = BeanFactory::getBean("Contacts", $this->contact_id); - $contact_temp->_create_proper_name_field(); - $this->contact_name = $contact_temp->full_name; + if(!empty($contact_temp)) { + $contact_temp->_create_proper_name_field(); + $this->contact_name = $contact_temp->full_name; + } } $call_fields['CONTACT_ID'] = $this->contact_id; @@ -485,7 +487,7 @@ class Call extends SugarBean { // rrs: bug 42684 - passing a contact breaks this call $notifyUser =($call->current_notify_user->object_name == 'User') ? $call->current_notify_user : $current_user; - + // Assumes $call dates are in user format $calldate = $timedate->fromDb($call->date_start); diff --git a/modules/Calls/CallHelper.php b/modules/Calls/CallHelper.php index fddf683b..26e1dadf 100644 --- a/modules/Calls/CallHelper.php +++ b/modules/Calls/CallHelper.php @@ -60,8 +60,7 @@ function getDurationMinutesOptions($focus, $field, $value, $view) { $focus->duration_hours = "0"; if (is_null($focus->duration_minutes)) $focus->duration_minutes = "1"; - - + if($view == 'EditView' || $view == 'MassUpdate' || $view == "QuickCreate" ) { $html = ' + {MOD.LBL_FROM_ADDR} - + {MOD.LBL_REPLY_NAME} - + {MOD.LBL_REPLY_ADDR} - + diff --git a/modules/Emails/EmailUI.php b/modules/Emails/EmailUI.php index 2937473d..cecdf0da 100644 --- a/modules/Emails/EmailUI.php +++ b/modules/Emails/EmailUI.php @@ -1939,6 +1939,10 @@ eoq; $ret['parent_type'] = $email->parent_type; $ret['parent_id'] = $email->parent_id; + if ($email->type == 'draft') { + $ret['cc'] = from_html($ccAddresses); + $ret['bcc'] = $bccAddresses; + } // reply all if(isset($_REQUEST['composeType']) && $_REQUEST['composeType'] == 'replyAll') { $ret['cc'] = from_html($ccAddresses); diff --git a/modules/Employees/Employee.php b/modules/Employees/Employee.php index 964c4562..0cf39417 100644 --- a/modules/Employees/Employee.php +++ b/modules/Employees/Employee.php @@ -126,7 +126,6 @@ class Employee extends Person { $result =$this->db->query($query, true, "Error filling in additional detail fields") ; $row = $this->db->fetchByAssoc($result); - $GLOBALS['log']->debug("additional detail query results: $row"); if($row != null) { diff --git a/modules/Home/action_view_map.php b/modules/Home/action_view_map.php index 4174959f..09b88b72 100644 --- a/modules/Home/action_view_map.php +++ b/modules/Home/action_view_map.php @@ -36,3 +36,4 @@ $action_view_map['additionaldetailsretrieve'] = 'additionaldetailsretrieve'; +$action_view_map['tour'] = 'tour'; \ No newline at end of file diff --git a/modules/Home/index.php b/modules/Home/index.php index 5bb67947..5304aac9 100644 --- a/modules/Home/index.php +++ b/modules/Home/index.php @@ -301,7 +301,6 @@ $resources = $sugarChart->getChartResources(); $mySugarResources = $sugarChart->getMySugarChartResources(); $sugar_smarty->assign('chartResources', $resources); $sugar_smarty->assign('mySugarChartResources', $mySugarResources); - if (file_exists("custom/include/MySugar/tpls/MySugar.tpl")) { echo $sugar_smarty->fetch('custom/include/MySugar/tpls/MySugar.tpl'); } else { diff --git a/modules/Home/language/en_us.lang.php b/modules/Home/language/en_us.lang.php index 242aadd0..2860630a 100644 --- a/modules/Home/language/en_us.lang.php +++ b/modules/Home/language/en_us.lang.php @@ -244,6 +244,34 @@ $mod_strings = array ( 'LBL_MORE_DETAIL' => 'More Detail' /*for 508 compliance fix*/, 'LBL_BASIC_SEARCH' => 'Basic Search' /*for 508 compliance fix*/, 'LBL_ADVANCED_SEARCH' => 'Advanced Search' /*for 508 compliance fix*/, + 'LBL_TOUR_HOME' => 'Home Icon', + 'LBL_TOUR_HOME_DESCRIPTION' => 'Quickly get back to your Home Page dashboard in one click.', + 'LBL_TOUR_MODULES' => 'Modules', + 'LBL_TOUR_MODULES_DESCRIPTION' => 'All your important modules are here.', + 'LBL_TOUR_MORE' => 'More Modules', + 'LBL_TOUR_MORE_DESCRIPTION' => 'The rest of your modules are here.', + 'LBL_TOUR_SEARCH' => 'Full Text Search', + 'LBL_TOUR_SEARCH_DESCRIPTION' => 'Search just got a whole lot better.', + 'LBL_TOUR_NOTIFICATIONS' => 'Notifications', + 'LBL_TOUR_NOTIFICATIONS_DESCRIPTION' => 'Sugar application notifications would go here.', + 'LBL_TOUR_PROFILE' => 'Profile', + 'LBL_TOUR_PROFILE_DESCRIPTION' => 'Access profile, settings and logout.', + 'LBL_TOUR_QUICKCREATE' => 'Quick Create', + 'LBL_TOUR_QUICKCREATE_DESCRIPTION' => 'Quickly create records without losing your place.', + 'LBL_TOUR_FOOTER' => 'Collapsible Footer', + 'LBL_TOUR_FOOTER_DESCRIPTION' => 'Easily expand and collapse the footer.', + 'LBL_TOUR_CUSTOM' => 'Custom Apps', + 'LBL_TOUR_CUSTOM_DESCRIPTION' => 'Custom integrations would go here.', + 'LBL_TOUR_BRAND' => 'Your Brand', + 'LBL_TOUR_BRAND_DESCRIPTION' => 'Your logo goes here. You can mouse over for more info.', + 'LBL_TOUR_WELCOME' => 'Welcome to Sugar', + 'LBL_TOUR_WATCH' => 'Watch What\'s New in Sugar', + 'LBL_TOUR_FEATURES' => '
    • New simplifed navigation bar
    • New collapsible footer
    • Improved Search
    • Updated actions menu

    and much more!

    ', + 'LBL_TOUR_VISIT' => 'For more information please visit our application', + 'LBL_TOUR_DONE' => 'You\'re Done!', + 'LBL_TOUR_REFERENCE_1' => 'You can always reference our', + 'LBL_TOUR_REFERENCE_2' => 'through the "Support" link under the profile tab.', + 'LNK_TOUR_DOCUMENTATION' => 'documentation' ); diff --git a/modules/Home/tour.css b/modules/Home/tour.css new file mode 100644 index 00000000..345d0a01 --- /dev/null +++ b/modules/Home/tour.css @@ -0,0 +1,276 @@ +/********************************************************************************* + * SugarCRM Community Edition is a customer relationship management program developed by + * SugarCRM, Inc. Copyright (C) 2004-2012 SugarCRM Inc. + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU Affero General Public License version 3 as published by the + * Free Software Foundation with the addition of the following permission added + * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK + * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY + * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more + * details. + * + * You should have received a copy of the GNU Affero General Public License along with + * this program; if not, see http://www.gnu.org/licenses or write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA. + * + * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road, + * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com. + * + * The interactive user interfaces in modified source and object code versions + * of this program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU Affero General Public License version 3. + * + * In accordance with Section 7(b) of the GNU Affero General Public License version 3, + * these Appropriate Legal Notices must retain the display of the "Powered by + * SugarCRM" logo. If the display of the logo is not reasonably feasible for + * technical reasons, the Appropriate Legal Notices must display the words + * "Powered by SugarCRM". + ********************************************************************************/ + +body +{ + padding-top: 50px; + line-height: 11px; +} + +form { + margin: 0px; +} +li { + line-height: 15px; +} + +h1, h2, h3, h4, h5, h6 { + font-family: Arial, Verdana, Helvetica, sans-serif; + font-weight: bold; +} + +.close:hover { + font-size: 20px; +} + + +#dcmenutop { + height: 0px; +} + +.list tr.pagination, +.list tr.pagination td, +.list tr.pagination td table +{ + height: auto; +} + +#footer img.logo { + height: auto; + width: auto; + background-image: none; +} + +.pagination button { + height: 30px; + width: 30px; + +} + +#zenbox_tab { +padding-top: 9px; +} + +.modal.whatsnew { + margin-top: -75px; + +} + +.modal a, +.popover a { + text-decoration: none; +} + +.modal-footer .btn-invisible { + float: left; + margin-left: 0px; +} +.modal-body { + font-size: 16px; + padding-bottom: 30px; +} + +.modal-footer .btn.btn-primary, +.popover-footer .btn.btn-primary { + color: #fff; +} + +.modal-footer { + padding-left: 0px; +} + +.modal ul li { + line-height: 18px; +} + +.modal p { + margin: 0 0 9px; +} + +h3.popover-title { + margin-bottom: 0px; +} +#tour { + width: auto; + margin: 0; + left: 0px; +} + +#tourEnd .modal-body p, +#tourEnd .modal-body a { + font-size: 18px; + line-height: 26px; +} +#tourEnd .modal-body p +{ + margin-top: 84px; +} + +li.icon-ok:before,i.icon-ok:before { + color: #3FB300; +} + +i.icon-arrow-up:before { + font-size: 40px; + +} +.caption { + font-size: 16px; + text-align: center; + margin-top: 10px; +} + +.pointer,.pointer.up{ + background-image: url('../../include/images/tour/arrow.png'); + background-repeat: no-repeat; + width: 42px; + height: 109px; +} + +.pointer.down { + background-position: 0px 109px; + background-position: 0px -109px\9; +} + + + +.pointer.up.left { + transform:rotate(-45deg); + -ms-transform:rotate(-45deg); /* IE 9 */ + -moz-transform:rotate(-45deg); /* Firefox */ + -webkit-transform:rotate(-45deg); /* Safari and Chrome */ + -o-transform:rotate(-45deg); /* Opera */ + width: 93px\0/; + height: 95px\0/; + background:transparent url('../../include/images/tour/arrow_ie.png') no-repeat 0px 100px\0/; + height: 110px \0/IE9; + +} + + +.pointer.up.right { + transform:rotate(45deg); + -ms-transform:rotate(45deg); /* IE 9 */ + -moz-transform:rotate(45deg); /* Firefox */ + -webkit-transform:rotate(45deg); /* Safari and Chrome */ + -o-transform:rotate(45deg); /* Opera */ + background-image: url('../../include/images/tour/arrow_ie.png')\0/; + background-repeat: no-repeat\0/; + background-position: 0px -280px\0/; + width: 93px\0/; + height: 95px\0/; + height: 110px \0/IE9; +} + + +.pointer.down.right { + transform:rotate(-45deg); + -ms-transform:rotate(-45deg); /* IE 9 */ + -moz-transform:rotate(-45deg); /* Firefox */ + -webkit-transform:rotate(-45deg); /* Safari and Chrome */ + -o-transform:rotate(-45deg); /* Opera */ + background-image: url(../../include/images/tour/arrow_ie.png)\0/; + background-repeat: no-repeat\0/; + background-position: 0px -280px\0/; + width: 93px\0/; + height: 95px\0/; + height: 110px \0/IE9; +} + +.pointer.down.left { + transform:rotate(45deg); + -ms-transform:rotate(45deg); /* IE 9 */ + -moz-transform:rotate(45deg); /* Firefox */ + -webkit-transform:rotate(45deg); /* Safari and Chrome */ + -o-transform:rotate(45deg); /* Opera */ + background-image: url(../../include/images/tour/arrow_ie.png)\0/; + background-repeat: no-repeat\0/; + background-position: 0px 280px\0/; + width: 93px\0/; + height: 95px\0/; + height: 110px \0/IE9; +} + + +:focus {outline:none;} +::-moz-focus-inner {border:0;} + +.rtl .modal { + direction: rtl; +} + +.rtl .modal-footer .btn { + float: left; +} + +.rtl .modal ul { + margin: 0 25px 9px 0px; +} + +.rtl .modal .close { + float: left; +} + +.rtl .pointer.up.right { + transform:rotate(-45deg); + -ms-transform:rotate(-45deg); /* IE 9 */ + -moz-transform:rotate(-45deg); /* Firefox */ + -webkit-transform:rotate(-45deg); /* Safari and Chrome */ + -o-transform:rotate(-45deg); /* Opera */ +} + +.rtl .pointer.up.left { + transform:rotate(45deg); + -ms-transform:rotate(45deg); /* IE 9 */ + -moz-transform:rotate(45deg); /* Firefox */ + -webkit-transform:rotate(45deg); /* Safari and Chrome */ + -o-transform:rotate(45deg); /* Opera */ +} + +.rtl .pointer.down.right { + transform:rotate(45deg); + -ms-transform:rotate(45deg); /* IE 9 */ + -moz-transform:rotate(45deg); /* Firefox */ + -webkit-transform:rotate(45deg); /* Safari and Chrome */ + -o-transform:rotate(45deg); /* Opera */ +} + +.rtl .pointer.down.left { + transform:rotate(-45deg); + -ms-transform:rotate(-45deg); /* IE 9 */ + -moz-transform:rotate(-45deg); /* Firefox */ + -webkit-transform:rotate(-45deg); /* Safari and Chrome */ + -o-transform:rotate(-45deg); /* Opera */ +} \ No newline at end of file diff --git a/modules/Home/tour.js b/modules/Home/tour.js new file mode 100644 index 00000000..797674e0 --- /dev/null +++ b/modules/Home/tour.js @@ -0,0 +1,35 @@ +/********************************************************************************* + * SugarCRM Community Edition is a customer relationship management program developed by + * SugarCRM, Inc. Copyright (C) 2004-2012 SugarCRM Inc. + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU Affero General Public License version 3 as published by the + * Free Software Foundation with the addition of the following permission added + * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK + * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY + * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more + * details. + * + * You should have received a copy of the GNU Affero General Public License along with + * this program; if not, see http://www.gnu.org/licenses or write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA. + * + * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road, + * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com. + * + * The interactive user interfaces in modified source and object code versions + * of this program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU Affero General Public License version 3. + * + * In accordance with Section 7(b) of the GNU Affero General Public License version 3, + * these Appropriate Legal Notices must retain the display of the "Powered by + * SugarCRM" logo. If the display of the logo is not reasonably feasible for + * technical reasons, the Appropriate Legal Notices must display the words + * "Powered by SugarCRM". + ********************************************************************************/ +var rtl=rtl=="undefined"?false:rtl;var modals=new Array();modals[0]={target:"#moduleTab_AllHome",title:SUGAR.language.get('Home','LBL_TOUR_HOME'),content:SUGAR.language.get('Home','LBL_TOUR_HOME_DESCRIPTION'),placement:"bottom"};modals[1]={target:"#moduleTab_AllAccounts",title:SUGAR.language.get('Home','LBL_TOUR_MODULES'),content:SUGAR.language.get('Home','LBL_TOUR_MODULES_DESCRIPTION'),placement:"bottom"};modals[2]={target:"#moduleTabExtraMenuAll",title:SUGAR.language.get('Home','LBL_TOUR_MORE'),content:SUGAR.language.get('Home','LBL_TOUR_MORE_DESCRIPTION'),placement:"bottom"};modals[3]={target:"#dcmenuSearchDiv",title:SUGAR.language.get('Home','LBL_TOUR_SEARCH'),content:SUGAR.language.get('Home','LBL_TOUR_SEARCH_DESCRIPTION'),placement:"bottom"};modals[4]={target:$("#dcmenuSugarCube").length==0?"#dcmenuSugarCubeEmpty":"#dcmenuSugarCube",title:SUGAR.language.get('Home','LBL_TOUR_NOTIFICATIONS'),content:SUGAR.language.get('Home','LBL_TOUR_NOTIFICATIONS_DESCRIPTION'),placement:"bottom"};modals[5]={target:"#globalLinksModule",title:SUGAR.language.get('Home','LBL_TOUR_PROFILE'),content:SUGAR.language.get('Home','LBL_TOUR_PROFILE_DESCRIPTION'),placement:"bottom"};modals[6]={target:"#quickCreate",title:SUGAR.language.get('Home','LBL_TOUR_QUICKCREATE'),content:SUGAR.language.get('Home','LBL_TOUR_QUICKCREATE_DESCRIPTION'),placement:"bottom right",leftOffset:rtl?-40:40,topOffset:-10};modals[7]={target:"#arrow",title:SUGAR.language.get('Home','LBL_TOUR_FOOTER'),content:SUGAR.language.get('Home','LBL_TOUR_FOOTER_DESCRIPTION'),placement:"top right",leftOffset:rtl?-90:80,topOffset:-40};modals[8]={target:"#integrations",title:SUGAR.language.get('Home','LBL_TOUR_CUSTOM'),content:SUGAR.language.get('Home','LBL_TOUR_CUSTOM_DESCRIPTION'),placement:"top",leftOffset:rtl?30:-30};modals[9]={target:"#logo",title:SUGAR.language.get('Home','LBL_TOUR_BRAND'),content:SUGAR.language.get('Home','LBL_TOUR_BRAND_DESCRIPTION'),placement:"top"};$(document).ready(function(){SUGAR.tour.init({id:'tour',modals:modals,modalUrl:"index.php?module=Home&action=tour&to_pdf=1",prefUrl:"index.php?module=Users&action=UpdateTourStatus&to_pdf=true&viewed=true",className:'whatsnew',onTourFinish:function(){$('#bootstrapJs').remove();$('#popoverext').remove();$('#bounce').remove();$('#bootstrapCss').remove();$('#tourCss').remove();$('#tourJs').remove();$('#whatsNewsJs').remove();}});}); \ No newline at end of file diff --git a/modules/Home/tour.tpl b/modules/Home/tour.tpl new file mode 100644 index 00000000..3a6cbd44 --- /dev/null +++ b/modules/Home/tour.tpl @@ -0,0 +1,98 @@ +{* +/********************************************************************************* + * SugarCRM Community Edition is a customer relationship management program developed by + * SugarCRM, Inc. Copyright (C) 2004-2012 SugarCRM Inc. + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU Affero General Public License version 3 as published by the + * Free Software Foundation with the addition of the following permission added + * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK + * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY + * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more + * details. + * + * You should have received a copy of the GNU Affero General Public License along with + * this program; if not, see http://www.gnu.org/licenses or write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA. + * + * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road, + * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com. + * + * The interactive user interfaces in modified source and object code versions + * of this program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU Affero General Public License version 3. + * + * In accordance with Section 7(b) of the GNU Affero General Public License version 3, + * these Appropriate Legal Notices must retain the display of the "Powered by + * SugarCRM" logo. If the display of the logo is not reasonably feasible for + * technical reasons, the Appropriate Legal Notices must display the words + * "Powered by SugarCRM". + ********************************************************************************/ + + +*} + +
    + + + +
    + + +
    + \ No newline at end of file diff --git a/modules/Home/views/view.tour.php b/modules/Home/views/view.tour.php new file mode 100644 index 00000000..231146e1 --- /dev/null +++ b/modules/Home/views/view.tour.php @@ -0,0 +1,49 @@ +ss->assign('mod', return_module_language($GLOBALS['current_language'], 'Home')); + $this->ss->assign("sugarFlavor",$sugar_flavor); + $this->ss->display('modules/Home/tour.tpl'); + } +} +?> diff --git a/modules/InboundEmail/InboundEmail.php b/modules/InboundEmail/InboundEmail.php index e1547e64..e60682b8 100644 --- a/modules/InboundEmail/InboundEmail.php +++ b/modules/InboundEmail/InboundEmail.php @@ -232,8 +232,10 @@ class InboundEmail extends SugarBean { */ function mark_deleted($id) { parent::mark_deleted($id); - $q = "update inbound_email set groupfolder_id = null WHERE id = '{$id}'"; - $r = $this->db->query($q); + + //bug52021 we need to keep the reference to the folders table in order for emails module to function properly + //$q = "update inbound_email set groupfolder_id = null WHERE id = '{$id}'"; + //$r = $this->db->query($q); $this->deleteCache(); } @@ -5238,15 +5240,15 @@ eoq; if (empty($trashFolder)) { $trashFolder = "INBOX.Trash"; } - foreach($uids as $uid) { - if($this->moveEmails($this->id, $this->mailbox, $this->id, $trashFolder, $uid)) - $GLOBALS['log']->debug("INBOUNDEMAIL: MoveEmail to {$trashFolder} successful."); - else { - $GLOBALS['log']->debug("INBOUNDEMAIL: MoveEmail to {$trashFolder} FAILED - trying hard delete for message: $uid"); - imap_delete($this->conn, $uid, FT_UID); - $return = true; - } - } + $uidsToMove = implode('::;::', $uids); + if($this->moveEmails($this->id, $this->mailbox, $this->id, $trashFolder, $uidsToMove)) + $GLOBALS['log']->debug("INBOUNDEMAIL: MoveEmail to {$trashFolder} successful."); + else { + $GLOBALS['log']->debug("INBOUNDEMAIL: MoveEmail to {$trashFolder} FAILED - trying hard delete for message: $uid"); + $uidsToDelete = implode(',', $uids); + imap_delete($this->conn, $uidsToDelete, FT_UID); + $return = true; + } } else { $msgnos = array(); diff --git a/modules/ModuleBuilder/Module/StudioModule.php b/modules/ModuleBuilder/Module/StudioModule.php index 61e43c62..b629aa6c 100644 --- a/modules/ModuleBuilder/Module/StudioModule.php +++ b/modules/ModuleBuilder/Module/StudioModule.php @@ -382,17 +382,9 @@ class StudioModule $bean_class = new $class(); //create new subpanel definition instance and get list of tabs - $spd = new SubPanelDefinitions($bean_class); - if (isset($spd->layout_defs['subpanel_setup'])) - { - foreach ($spd->layout_defs['subpanel_setup'] as $panelname) - { - if ($panelname['module'] == $subpanel) - { - $spd_arr[] = array('mod_name' => $mod_name, - 'panel_name' => $panelname['get_subpanel_data']); - } - } + $spd = new SubPanelDefinitions($bean_class) ; + if ( isset($spd->layout_defs['subpanel_setup'][strtolower($subpanel)]['module']) ){ + $spd_arr[] = $mod_name; } } return $spd_arr; @@ -423,11 +415,9 @@ class StudioModule foreach($data as $parentModule){ //If this module type doesn't support a given metadata type, we will get an exception from getParser() try { - $parser = ParserFactory::getParser(MB_LISTVIEW, $parentModule['mod_name'], null, $parentModule['panel_name']); - if ($parser->removeField($fieldName)) - { - $parser->handleSave(false); - } + $parser = ParserFactory::getParser( MB_LISTVIEW , $parentModule, null , $this->module) ; + if ($parser->removeField ( $fieldName ) ) + $parser->handleSave(false) ; } catch(Exception $e){} } } diff --git a/modules/ModuleBuilder/javascript/studio2.js b/modules/ModuleBuilder/javascript/studio2.js index cdabfcfa..21274766 100644 --- a/modules/ModuleBuilder/javascript/studio2.js +++ b/modules/ModuleBuilder/javascript/studio2.js @@ -168,6 +168,20 @@ Studio2 = { ModuleBuilder.helpRegisterByID('layoutEditorButtons','input'); ModuleBuilder.helpSetup('layoutEditor','default'); + var elem = document.getElementById('prepareForSave').elements; + if (elem != null) { + var has_tab = false; + + for (var i = 0; i < elem.length; i++) { + if (elem[i].name.match(/^tabDefs_.*_newTab$/)) { + if (elem[i].value == '1' && elem[i].name != 'tabDefs_' + Studio2.firstPanelId + '_newTab') + has_tab = true; + } + } + if (has_tab == true) { + document.getElementById('le_paneltype_select_' + Studio2.firstPanelIdCount).disabled = true; + } + } }, resizeDivs : function () { @@ -984,4 +998,5 @@ Studio2 = { } }; - +Studio2.firstPanelId = ""; +Studio2.firstPanelIdCount = 0; diff --git a/modules/ModuleBuilder/language/en_us.lang.php b/modules/ModuleBuilder/language/en_us.lang.php index af8a2a3c..638693e7 100644 --- a/modules/ModuleBuilder/language/en_us.lang.php +++ b/modules/ModuleBuilder/language/en_us.lang.php @@ -413,8 +413,15 @@ $mod_strings = array( 'LBL_ADD_DROPDOWN' => 'Add a new Global Dropdown', 'LBL_BLANK' => '-blank-', 'LBL_TAB_ORDER' => 'Tab Order', -'LBL_TAB_PANELS' => 'Display panels as tabs', -'LBL_TAB_PANELS_HELP' => 'Display each panel as its own tab instead of having them all appear on one screen', +'LBL_TAB_PANELS' => 'Enable tabs', +'LBL_TAB_PANELS_HELP' => 'When tabs are enabled, use the "type" dropdown box
    for each section to define how it will be displayed (tab or panel)', +'LBL_TABDEF_TYPE' => 'Display Type', +'LBL_TABDEF_TYPE_HELP' => 'Select how this section should be displayed. This option only has effect if you have enabled tabs on this view.', +'LBL_TABDEF_TYPE_OPTION_TAB' => 'Tab', +'LBL_TABDEF_TYPE_OPTION_PANEL' => 'Panel', +'LBL_TABDEF_TYPE_OPTION_HELP' => 'Select Panel to have this panel display within the view of the layout. Select Tab to have this panel displayed within a separate tab within the layout. When Tab is specified for a panel, subsequent panels set to display as Panel will be displayed within the tab.
    A new Tab will be started for the next panel for which Tab is selected. If Tab is selected for a panel below the first panel, the first panel will necessarily be a Tab.', +'LBL_TABDEF_COLLAPSE' => 'Collapse', +'LBL_TABDEF_COLLAPSE_HELP' => 'Select to make the default state of this panel collapsed.', 'LBL_DROPDOWN_TITLE_NAME' => 'Name', 'LBL_DROPDOWN_LANGUAGE' => 'Language', 'LBL_DROPDOWN_ITEMS' => 'List Items', diff --git a/modules/ModuleBuilder/parsers/ParserFactory.php b/modules/ModuleBuilder/parsers/ParserFactory.php index 7c62e305..fa6068ed 100644 --- a/modules/ModuleBuilder/parsers/ParserFactory.php +++ b/modules/ModuleBuilder/parsers/ParserFactory.php @@ -159,7 +159,7 @@ class ParserFactory if (!empty($def['view']) && $def['view'] == strtolower($view) && !empty($def['parser'])) { $pName = $def['parser']; - $path = "module/ModuleBuilder/parsers/views/{$pName}.php"; + $path = "modules/ModuleBuilder/parsers/views/{$pName}.php"; if (file_exists("custom/$path")) require_once("custom/$path"); else if (file_exists($path)) diff --git a/modules/ModuleBuilder/parsers/views/GridLayoutMetaDataParser.php b/modules/ModuleBuilder/parsers/views/GridLayoutMetaDataParser.php index 72751fb7..88dc6316 100644 --- a/modules/ModuleBuilder/parsers/views/GridLayoutMetaDataParser.php +++ b/modules/ModuleBuilder/parsers/views/GridLayoutMetaDataParser.php @@ -167,6 +167,52 @@ class GridLayoutMetaDataParser extends AbstractMetaDataParser implements MetaDat return $viewdefs ; } + /* + * Return the tab definitions for tab/panel combo + */ + function getTabDefs () + { + $tabDefs = array(); + $this->setUseTabs( false ); + foreach ( $this->_viewdefs [ 'panels' ] as $panelID => $panel ) + { + + $tabDefs [ strtoupper($panelID) ] = array(); + + // panel or tab setting + if ( isset($this->_viewdefs [ 'templateMeta' ] [ 'tabDefs' ] [ strtoupper($panelID) ] [ 'newTab' ]) + && is_bool($this->_viewdefs [ 'templateMeta' ] [ 'tabDefs' ] [ strtoupper($panelID) ] [ 'newTab' ])) + { + $tabDefs [ strtoupper($panelID) ] [ 'newTab' ] = $this->_viewdefs [ 'templateMeta' ] [ 'tabDefs' ] [ strtoupper($panelID) ] [ 'newTab' ]; + if ($tabDefs [ strtoupper($panelID) ] [ 'newTab' ] == true) + $this->setUseTabs( true ); + } + else + { + $tabDefs [ strtoupper($panelID) ] [ 'newTab' ] = false; + } + + // collapsed panels + if ( isset($this->_viewdefs [ 'templateMeta' ] [ 'tabDefs' ] [ strtoupper($panelID) ] [ 'panelDefault' ]) + && $this->_viewdefs [ 'templateMeta' ] [ 'tabDefs' ] [ strtoupper($panelID) ] [ 'panelDefault' ] == 'collapsed' ) + { + $tabDefs [ strtoupper($panelID) ] [ 'panelDefault' ] = 'collapsed'; + } + else + { + $tabDefs [ strtoupper($panelID) ] [ 'panelDefault' ] = 'expanded'; + } + } + return $tabDefs; + } + + /* + * Set tab definitions + */ + function setTabDefs($tabDefs) { + $this->_viewdefs [ 'templateMeta' ] [ 'tabDefs' ] = $tabDefs; + } + function getMaxColumns () { if (!empty( $this->_viewdefs) && isset($this->_viewdefs [ 'templateMeta' ] [ 'maxColumns' ])) @@ -450,7 +496,8 @@ class GridLayoutMetaDataParser extends AbstractMetaDataParser implements MetaDat } } - + +/* //Set the tabs setting if (isset($_REQUEST['panels_as_tabs'])) { @@ -459,7 +506,39 @@ class GridLayoutMetaDataParser extends AbstractMetaDataParser implements MetaDat else $this->setUseTabs( true ); } - +*/ + + //Set the tab definitions + $tabDefs = array(); + $this->setUseTabs( false ); + foreach ( $this->_viewdefs [ 'panels' ] as $panelID => $panel ) + { + // panel or tab setting + $tabDefs [ strtoupper($panelID) ] = array(); + if ( isset($_REQUEST['tabDefs_'.$panelID.'_newTab']) ) + { + $tabDefs [ strtoupper($panelID) ] [ 'newTab' ] = ( $_REQUEST['tabDefs_'.$panelID.'_newTab'] == '1' ) ? true : false; + if ($tabDefs [ strtoupper($panelID) ] [ 'newTab' ] == true) + $this->setUseTabs( true ); + } + else + { + $tabDefs [ strtoupper($panelID) ] [ 'newTab' ] = false; + } + + // collapse panel + if ( isset($_REQUEST['tabDefs_'.$panelID.'_panelDefault']) ) + { + $tabDefs [ strtoupper($panelID) ] [ 'panelDefault' ] = ( $_REQUEST['tabDefs_'.$panelID.'_panelDefault'] == 'collapsed' ) ? 'collapsed' : 'expanded'; + } + else + { + $tabDefs [ strtoupper($panelID) ] [ 'panelDefault' ] = 'expanded'; + } + + } + $this->setTabDefs($tabDefs); + //bug: 38232 - Set the sync detail and editview settings if (isset($_REQUEST['sync_detail_and_edit'])) { @@ -537,7 +616,7 @@ class GridLayoutMetaDataParser extends AbstractMetaDataParser implements MetaDat $newRow = array ( ) ; foreach ( $row as $colID => $fieldname ) { - if ($fieldname == null || !isset($fielddefs[$fieldname])) + if ($fieldname == null ) continue; //Backwards compatibility and a safeguard against multiple calls to _convertToCanonicalForm @@ -545,7 +624,9 @@ class GridLayoutMetaDataParser extends AbstractMetaDataParser implements MetaDat { $newRow [ $colID - $offset ] = $fieldname; continue; - } + }else if(!isset($fielddefs[$fieldname])){ + continue; + } //Replace (filler) with the empty string if ($fieldname == $this->FILLER[ 'name' ]) { diff --git a/modules/ModuleBuilder/tpls/layoutView.tpl b/modules/ModuleBuilder/tpls/layoutView.tpl index c5e3dfa9..93d1bf2a 100644 --- a/modules/ModuleBuilder/tpls/layoutView.tpl +++ b/modules/ModuleBuilder/tpls/layoutView.tpl @@ -46,11 +46,6 @@ {$buttons} - {if empty($disable_tabs)} - - {/if} {if $view == 'editview'}
    - {sugar_translate label="LBL_TAB_PANELS" module="ModuleBuilder"} {sugar_help text=$mod.LBL_TAB_PANELS_HELP} - {sugar_translate label="LBL_SYNC_TO_DETAILVIEW" module="ModuleBuilder"} {sugar_help text=$mod.LBL_SYNC_TO_DETAILVIEW_HELP} @@ -126,6 +121,7 @@

    {$layouttitle}

    +{counter name='idCounter' assign='idCounter' start='1'} {foreach from=$layout item='panel' key='panelid'}
    @@ -145,9 +141,26 @@ {$panelid}
    {if $panelid ne 'default'} - {capture assign="otherAttributes"}class="le_edit" style="float:right; cursor:pointer;" onclick="editPanelProperties('{$idCount}');"{/capture} + {capture assign="otherAttributes"}class="le_edit" style="float:left; cursor:pointer;" onclick="editPanelProperties('{$idCount}');"{/capture} {sugar_getimage name="edit_inline" ext=".gif" other_attributes=$otherAttributes} {/if} + +   {sugar_translate label="LBL_TABDEF_TYPE" module="ModuleBuilder"} {sugar_help text=$mod.LBL_TABDEF_TYPE_OPTION_HELP}: + {if $idCounter == 1} + {assign var="firstpanelid" value=$panelid} + {assign var="firstpanelidcount" value=$idCount} + {/if} + + + +  {sugar_translate label="LBL_TABDEF_COLLAPSE" module="ModuleBuilder"}? + + {counter name='idCount' assign='idCount' print=false} {foreach from=$panel item='row' key='rid'} @@ -200,6 +213,7 @@ {/foreach}
    + {counter name='idCounter' assign='idCounter' print=false} {/foreach} @@ -211,6 +225,11 @@ +{foreach from=$layout item='panel' key='panelid'} +{capture name=panel_upper assign=panel_upper}{$panelid|upper}{/capture} + + +{/foreach} {if $fromPortal} @@ -237,7 +256,35 @@ var editPanelProperties = function (panelId, view) { + "&view=" + encodeURIComponent(view) + "&id_label=le_panelname_" + encodeURIComponent(panelId) + "&name_label=label_" + encodeURIComponent(key_label.toUpperCase()) + "&title_label=" + encodeURIComponent(SUGAR.language.get("ModuleBuilder", "LBL_LABEL_TITLE")) + "&value_label=" + encodeURIComponent(value_label); ModuleBuilder.getContent(params); -}; +}; + +var showHideBox = function (newTab, idCount, panelId, firstPanelId, firstPanelIdCount) { + var collapseBox = document.getElementById('le_panelcollapse_' + idCount); + if (newTab == "1") { + collapseBox.style.display = 'none'; + if (idCount != firstPanelIdCount) { + document.getElementById('le_paneltype_select_' + firstPanelIdCount).options[1].selected = true; + document.getElementById('le_panelcollapse_' + firstPanelIdCount).style.display = 'none'; + document.forms.prepareForSave['tabDefs_' + firstPanelId + '_newTab'].value = '1'; + document.getElementById('le_paneltype_select_' + firstPanelIdCount).disabled = true; + } + } + else { + var elem = document.getElementById('prepareForSave').elements; + var has_tab = false; + collapseBox.style.display = 'block'; + for (var i = 0; i < elem.length; i++) { + if (elem[i].name.match(/^tabDefs_.*_newTab$/)) { + if (elem[i].value == '1' && elem[i].name != panelId && elem[i].name != 'tabDefs_'+firstPanelId+'_newTab') + has_tab = true; + } + } + if (has_tab == false) { + document.getElementById('le_paneltype_select_' + firstPanelIdCount).disabled = false; + } + } +}; + {/literal} var editFieldProperties = function (idCount, label) {ldelim} var value_label = document.getElementById('le_label_' + idCount).innerHTML.replace(/^\s+|\s+$/g,''); @@ -256,6 +303,8 @@ var editFieldProperties = function (idCount, label) {ldelim} {rdelim} +Studio2.firstPanelId = "{$firstpanelid}"; +Studio2.firstPanelIdCount = {$firstpanelidcount}; Studio2.init(); if('{$view}'.toLowerCase() != 'editview') ModuleBuilder.helpSetup('layoutEditor','default'+'{$view}'.toLowerCase()); diff --git a/modules/ModuleBuilder/views/view.layoutview.php b/modules/ModuleBuilder/views/view.layoutview.php index a8b6f1a8..c88abbb2 100644 --- a/modules/ModuleBuilder/views/view.layoutview.php +++ b/modules/ModuleBuilder/views/view.layoutview.php @@ -228,6 +228,7 @@ class ViewLayoutView extends ViewEdit $smarty->assign ( 'maxColumns', $parser->getMaxColumns() ) ; $smarty->assign ( 'nextPanelId', $parser->getFirstNewPanelId() ) ; $smarty->assign ( 'displayAsTabs', $parser->getUseTabs() ) ; + $smarty->assign ( 'tabDefs', $parser->getTabDefs() ) ; $smarty->assign ( 'syncDetailEditViews', $parser->getSyncDetailEditViews() ) ; $smarty->assign ( 'fieldwidth', 150 ) ; $smarty->assign ( 'translate', $this->fromModuleBuilder ? false : true ) ; diff --git a/modules/Project/tpls/QuickEditFooter.tpl b/modules/Project/tpls/QuickEditFooter.tpl new file mode 100644 index 00000000..ffed0d26 --- /dev/null +++ b/modules/Project/tpls/QuickEditFooter.tpl @@ -0,0 +1,61 @@ +{* +/********************************************************************************* + * SugarCRM Community Edition is a customer relationship management program developed by + * SugarCRM, Inc. Copyright (C) 2004-2012 SugarCRM Inc. + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU Affero General Public License version 3 as published by the + * Free Software Foundation with the addition of the following permission added + * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK + * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY + * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more + * details. + * + * You should have received a copy of the GNU Affero General Public License along with + * this program; if not, see http://www.gnu.org/licenses or write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA. + * + * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road, + * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com. + * + * The interactive user interfaces in modified source and object code versions + * of this program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU Affero General Public License version 3. + * + * In accordance with Section 7(b) of the GNU Affero General Public License version 3, + * these Appropriate Legal Notices must retain the display of the "Powered by + * SugarCRM" logo. If the display of the logo is not reasonably feasible for + * technical reasons, the Appropriate Legal Notices must display the words + * "Powered by SugarCRM". + ********************************************************************************/ + + +*} + + + + +
    + {if $bean->aclAccess("save")}{/if} + {{foreach from=$form.buttons key=val item=button}} + {{sugar_button module="$module" id="$button" view="$view"}} + {{/foreach}} + + + + {$APP.LBL_REQUIRED_SYMBOL} {$APP.NTC_REQUIRED} +
    + \ No newline at end of file diff --git a/modules/Project/tpls/QuickEditHeader.tpl b/modules/Project/tpls/QuickEditHeader.tpl new file mode 100644 index 00000000..a6fde981 --- /dev/null +++ b/modules/Project/tpls/QuickEditHeader.tpl @@ -0,0 +1,104 @@ +{* +/********************************************************************************* + * SugarCRM Community Edition is a customer relationship management program developed by + * SugarCRM, Inc. Copyright (C) 2004-2012 SugarCRM Inc. + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU Affero General Public License version 3 as published by the + * Free Software Foundation with the addition of the following permission added + * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK + * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY + * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more + * details. + * + * You should have received a copy of the GNU Affero General Public License along with + * this program; if not, see http://www.gnu.org/licenses or write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA. + * + * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road, + * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com. + * + * The interactive user interfaces in modified source and object code versions + * of this program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU Affero General Public License version 3. + * + * In accordance with Section 7(b) of the GNU Affero General Public License version 3, + * these Appropriate Legal Notices must retain the display of the "Powered by + * SugarCRM" logo. If the display of the logo is not reasonably feasible for + * technical reasons, the Appropriate Legal Notices must display the words + * "Powered by SugarCRM". + ********************************************************************************/ + +*} + + +
    +
    + + + + + +
    + +{if isset($smarty.request.isDuplicate) && $smarty.request.isDuplicate eq "true"} + + + +{else} + +{/if} + + + + + + + +{if !empty($smarty.request.return_module) || !empty($smarty.request.relate_to)} + + +{/if} + + +{assign var='place' value="_HEADER"} +{{if isset($form.hidden)}} +{{foreach from=$form.hidden item=field}} +{{$field}} +{{/foreach}} +{{/if}} +{{if empty($form.button_location) || $form.button_location == 'top'}} +{{if !empty($form) && !empty($form.buttons)}} + {{foreach from=$form.buttons key=val item=button}} + {{sugar_button module="$module" id="$button" form_id="$form_id" view="$view" appendTo="header_buttons" location="HEADER"}} + {{/foreach}} +{{else}} +{{sugar_button module="$module" id="SAVE" view="$view" form_id="$form_id" location="HEADER" appendTo="header_buttons"}} +{{sugar_button module="$module" id="CANCEL" view="$view" form_id="$form_id" location="HEADER" appendTo="header_buttons"}} +{{/if}} +{{if empty($form.hideAudit) || !$form.hideAudit}} +{{sugar_button module="$module" id="Audit" view="$view" form_id="$form_id" appendTo="header_buttons"}} +{{/if}} +{{/if}} +{{sugar_action_menu buttons=$header_buttons class="fancymenu" flat=true}} +{{$ADMIN_EDIT}} +{{if $panelCount == 0}} + {{* Render tag for VCR control if SHOW_VCR_CONTROL is true *}} + {{if $SHOW_VCR_CONTROL}} + {$PAGINATION} + {{/if}} +{{/if}} +
    diff --git a/modules/Project/views/view.quickedit.php b/modules/Project/views/view.quickedit.php new file mode 100644 index 00000000..f8d77ac0 --- /dev/null +++ b/modules/Project/views/view.quickedit.php @@ -0,0 +1,84 @@ +bean->retrieve($_REQUEST['record']); + if($this->bean->is_template == 1){ + $this->footerTpl = 'modules/Project/tpls/QuickEditFooter.tpl'; + $this->headerTpl = 'modules/Project/tpls/QuickEditHeader.tpl'; + $this->defaultButtons = array('DCMENUCANCEL'); + } + } + return parent::preDisplay(); + } + +} \ No newline at end of file diff --git a/modules/Schedulers/_AddJobsHere.php b/modules/Schedulers/_AddJobsHere.php index 4f867972..4a3c6eef 100644 --- a/modules/Schedulers/_AddJobsHere.php +++ b/modules/Schedulers/_AddJobsHere.php @@ -308,9 +308,9 @@ function pruneDatabase() { while($aDel = $db->fetchByAssoc($rDel, false)) { // build column names - $queryString[] = $db->insertParams($table, $columns, $rDel, null, false); + $queryString[] = $db->insertParams($table, $columns, $aDel, null, false); - if(!empty($custom_columns) && !empty($rDel['id'])) { + if(!empty($custom_columns) && !empty($aDel['id'])) { $qDelCstm = 'SELECT * FROM '.$table.'_cstm WHERE id_c = '.$db->quoted($aDel['id']); $rDelCstm = $db->query($qDelCstm); diff --git a/modules/UpgradeWizard/end.php b/modules/UpgradeWizard/end.php index 37e544fd..a729cfbd 100644 --- a/modules/UpgradeWizard/end.php +++ b/modules/UpgradeWizard/end.php @@ -263,6 +263,15 @@ if(function_exists('upgradeDisplayedTabsAndSubpanels')) upgradeDisplayedTabsAndSubpanels($_SESSION['current_db_version']); } +if ($_SESSION['current_db_version'] < '650') +{ + // Bug 53650 - Workflow Type Templates not saving Type upon upgrade to 6.5.0, usable as Email Templates + $db->query("UPDATE email_templates SET type = 'workflow' WHERE + coalesce(" . $db->convert("base_module", "length") . ",0) > 0 + AND + coalesce(" . $db->convert("type", "length") . ",0) = 0 + "); +} //Unlink files that have been removed if(function_exists('unlinkUpgradeFiles')) @@ -408,4 +417,4 @@ $stepRecheck = 0; $_SESSION['step'][$steps['files'][$_REQUEST['step']]] = ($stop) ? 'failed' : 'success'; unset($_SESSION['current_db_version']); -unset($_SESSION['target_db_version']); \ No newline at end of file +unset($_SESSION['target_db_version']); diff --git a/modules/UpgradeWizard/silentUpgrade_step2.php b/modules/UpgradeWizard/silentUpgrade_step2.php index 0c0e6030..6947329e 100644 --- a/modules/UpgradeWizard/silentUpgrade_step2.php +++ b/modules/UpgradeWizard/silentUpgrade_step2.php @@ -541,6 +541,16 @@ if(function_exists('upgradeDisplayedTabsAndSubpanels')) upgradeDisplayedTabsAndSubpanels($origVersion); } +if ($origVersion < '650') +{ + // Bug 53650 - Workflow Type Templates not saving Type upon upgrade to 6.5.0, usable as Email Templates + $db->query("UPDATE email_templates SET type = 'workflow' WHERE + coalesce(" . $db->convert("base_module", "length") . ",0) > 0 + AND + coalesce(" . $db->convert("type", "length") . ",0) = 0 + "); +} + //Unlink files that have been removed if(function_exists('unlinkUpgradeFiles')) { diff --git a/modules/Users/Changenewpassword.php b/modules/Users/Changenewpassword.php index 4ea2004d..8821914b 100644 --- a/modules/Users/Changenewpassword.php +++ b/modules/Users/Changenewpassword.php @@ -103,7 +103,8 @@ if(isset($_REQUEST['recaptcha_challenge_field']) && isset($_REQUEST['recaptcha_r $redirect='1'; if (isset($_REQUEST['guid'])) { - $Q="select * from users_password_link where id='".$_REQUEST['guid']."' and deleted='0'"; + // Change 'deleted = 0' clause to 'COALESCE(deleted, 0) = 0' because by default the values were NULL + $Q = "SELECT * FROM users_password_link WHERE id = '" . $_REQUEST['guid'] . "' AND COALESCE(deleted, 0) = '0'"; $result =$GLOBALS['db']->limitQuery($Q,0,1,false); $row = $GLOBALS['db']->fetchByAssoc($result); if (!empty($row)){ diff --git a/modules/Users/Save.php b/modules/Users/Save.php index db172d3d..380e92bb 100644 --- a/modules/Users/Save.php +++ b/modules/Users/Save.php @@ -194,7 +194,7 @@ if(!$current_user->is_admin && !$GLOBALS['current_user']->isAdminForModule('Use } if((isset($_POST['is_admin']) && ($_POST['is_admin'] == 'on' || $_POST['is_admin'] == '1')) || (isset($_POST['UserType']) && $_POST['UserType'] == "Administrator")) $focus->is_admin = 1; - elseif(empty($_POST['is_admin'])) $focus->is_admin = 0; + elseif(isset($_POST['is_admin']) && empty($_POST['is_admin'])) $focus->is_admin = 0; //if(empty($_POST['portal_only']) || !empty($_POST['is_admin'])) $focus->portal_only = 0; //if(empty($_POST['is_group']) || !empty($_POST['is_admin'])) $focus->is_group = 0; if(empty($_POST['receive_notifications'])) $focus->receive_notifications = 0; diff --git a/modules/Users/UpdateTourStatus.php b/modules/Users/UpdateTourStatus.php new file mode 100644 index 00000000..fef1e594 --- /dev/null +++ b/modules/Users/UpdateTourStatus.php @@ -0,0 +1,42 @@ +setPreference('viewed_tour',$_REQUEST['viewed']); diff --git a/modules/Users/login.tpl b/modules/Users/login.tpl index 1771c1bf..a2f03ac3 100644 --- a/modules/Users/login.tpl +++ b/modules/Users/login.tpl @@ -60,7 +60,8 @@ var LBL_HIDEOPTIONS = '{sugar_translate module="Users" label="LBL_HIDEOPTIONS"}'