PageRenderTime 61ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 1ms

/modules/Emails/EmailUI.php

https://github.com/mikmagic/sugarcrm_dev
PHP | 2963 lines | 2519 code | 204 blank | 240 comment | 72 complexity | 4a84724f5f101fcd4e9f2e5a4ba360e5 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, LGPL-2.1, BSD-3-Clause, AGPL-3.0

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
  3. /*********************************************************************************
  4. * SugarCRM Community Edition is a customer relationship management program developed by
  5. * SugarCRM, Inc. Copyright (C) 2004-2011 SugarCRM Inc.
  6. *
  7. * This program is free software; you can redistribute it and/or modify it under
  8. * the terms of the GNU Affero General Public License version 3 as published by the
  9. * Free Software Foundation with the addition of the following permission added
  10. * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
  11. * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
  12. * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
  13. *
  14. * This program is distributed in the hope that it will be useful, but WITHOUT
  15. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  16. * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
  17. * details.
  18. *
  19. * You should have received a copy of the GNU Affero General Public License along with
  20. * this program; if not, see http://www.gnu.org/licenses or write to the Free
  21. * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  22. * 02110-1301 USA.
  23. *
  24. * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
  25. * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
  26. *
  27. * The interactive user interfaces in modified source and object code versions
  28. * of this program must display Appropriate Legal Notices, as required under
  29. * Section 5 of the GNU Affero General Public License version 3.
  30. *
  31. * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
  32. * these Appropriate Legal Notices must retain the display of the "Powered by
  33. * SugarCRM" logo. If the display of the logo is not reasonably feasible for
  34. * technical reasons, the Appropriate Legal Notices must display the words
  35. * "Powered by SugarCRM".
  36. ********************************************************************************/
  37. /*********************************************************************************
  38. * Description:
  39. * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc. All Rights
  40. * Reserved. Contributor(s): ______________________________________..
  41. *********************************************************************************/
  42. require_once("include/ytree/Tree.php");
  43. require_once("include/ytree/ExtNode.php");
  44. require_once("include/SugarFolders/SugarFolders.php");
  45. class EmailUI {
  46. var $db;
  47. var $folder; // place holder for SugarFolder object
  48. var $folderStates = array(); // array of folderPath names and their states (1/0)
  49. var $smarty;
  50. var $addressSeparators = array(";", ",");
  51. var $rolloverStyle = "<style>div#rollover {position: relative;float: left;margin: none;text-decoration: none;}div#rollover a:hover {padding: 0;}div#rollover a span {display: none;}div#rollover a:hover span {text-decoration: none;display: block;width: 250px;margin-top: 5px;margin-left: 5px;position: absolute;padding: 10px;color: #333; border: 1px solid #ccc; background-color: #fff; font-size: 12px;z-index: 1000;}</style>\n";
  52. var $groupCss = "<span class='groupInbox'>";
  53. var $cacheTimeouts = array(
  54. 'messages' => 86400, // 24 hours
  55. 'folders' => 300, // 5 mins
  56. 'attachments' => 86400, // 24 hours
  57. );
  58. var $userCacheDir = '';
  59. var $coreDynamicFolderQuery = "SELECT emails.id polymorphic_id, 'Emails' polymorphic_module FROM emails
  60. JOIN emails_text on emails.id = emails_text.email_id
  61. WHERE (type = '::TYPE::' OR status = '::STATUS::') AND assigned_user_id = '::USER_ID::' AND emails.deleted = '0'";
  62. /**
  63. * Sole constructor
  64. */
  65. function EmailUI() {
  66. global $sugar_config;
  67. global $current_user;
  68. $folderStateSerial = $current_user->getPreference('folderOpenState', 'Emails');
  69. if(!empty($folderStateSerial)) {
  70. $this->folderStates = unserialize($folderStateSerial);
  71. }
  72. $this->smarty = new Sugar_Smarty();
  73. $this->folder = new SugarFolder();
  74. $this->userCacheDir = "{$sugar_config['cache_dir']}modules/Emails/{$current_user->id}";
  75. $this->db = DBManagerFactory::getInstance();
  76. }
  77. ///////////////////////////////////////////////////////////////////////////
  78. //// CORE
  79. /**
  80. * Renders the frame for emails
  81. */
  82. function displayEmailFrame() {
  83. require_once("include/OutboundEmail/OutboundEmail.php");
  84. global $app_strings, $app_list_strings;
  85. global $mod_strings;
  86. global $sugar_config;
  87. global $current_user;
  88. global $locale;
  89. global $timedate;
  90. global $theme;
  91. global $sugar_version;
  92. global $sugar_flavor;
  93. global $current_language;
  94. global $server_unique_key;
  95. $this->preflightUserCache();
  96. $ie = new InboundEmail();
  97. // focus listView
  98. $list = array(
  99. 'mbox' => 'Home',
  100. 'ieId' => '',
  101. 'name' => 'Home',
  102. 'unreadChecked' => 0,
  103. 'out' => array(),
  104. );
  105. $this->_generateComposeConfigData('email_compose');
  106. //Check quick create module access
  107. $QCAvailableModules = $this->_loadQuickCreateModules();
  108. //Get the quickSearch js needed for assigned user id on Search Tab
  109. require_once('include/QuickSearchDefaults.php');
  110. $qsd = new QuickSearchDefaults();
  111. $qsd->setFormName('advancedSearchForm');
  112. $quicksearchAssignedUser = "if(typeof sqs_objects == 'undefined'){var sqs_objects = new Array;}";
  113. $quicksearchAssignedUser .= "sqs_objects['advancedSearchForm_assigned_user_name']=" . json_encode($qsd->getQSUser()) . ";";
  114. $qsd->setFormName('Distribute');
  115. $quicksearchAssignedUser .= "sqs_objects['Distribute_assigned_user_name']=" . json_encode($qsd->getQSUser()) . ";";
  116. $this->smarty->assign('quickSearchForAssignedUser', $quicksearchAssignedUser);
  117. ///////////////////////////////////////////////////////////////////////
  118. //// BASIC ASSIGNS
  119. $this->smarty->assign("currentUserId",$current_user->id);
  120. $this->smarty->assign("CURRENT_USER_EMAIL",$current_user->email1);
  121. $this->smarty->assign("currentUserName",$current_user->name);
  122. $this->smarty->assign('yuiPath', 'modules/Emails/javascript/yui-ext/');
  123. $this->smarty->assign('app_strings', $app_strings);
  124. $this->smarty->assign('mod_strings', $mod_strings);
  125. $this->smarty->assign('theme', $theme);
  126. $this->smarty->assign('sugar_config', $sugar_config);
  127. $this->smarty->assign('is_admin', $current_user->is_admin);
  128. $this->smarty->assign('sugar_version', $sugar_version);
  129. $this->smarty->assign('sugar_flavor', $sugar_flavor);
  130. $this->smarty->assign('current_language', $current_language);
  131. $this->smarty->assign('server_unique_key', $server_unique_key);
  132. $this->smarty->assign('qcModules', json_encode($QCAvailableModules));
  133. $extAllDebugValue = "ext-all.js";
  134. $this->smarty->assign('extFileName', $extAllDebugValue);
  135. // settings: general
  136. $e2UserPreferences = $this->getUserPrefsJS();
  137. $emailSettings = $e2UserPreferences['emailSettings'];
  138. ///////////////////////////////////////////////////////////////////////
  139. //// USER SETTINGS
  140. // settings: accounts
  141. $cuDatePref = $current_user->getUserDateTimePreferences();
  142. $this->smarty->assign('dateFormat', $cuDatePref['date']);
  143. $this->smarty->assign('dateFormatExample', str_replace(array("Y", "m", "d"), array("yyyy", "mm", "dd"), $cuDatePref['date']));
  144. $this->smarty->assign('calFormat', $timedate->get_cal_date_format());
  145. $this->smarty->assign('TIME_FORMAT', $timedate->get_user_time_format());
  146. $ieAccounts = $ie->retrieveByGroupId($current_user->id);
  147. $ieAccountsOptions = "<option value=''>{$app_strings['LBL_NONE']}</option>\n";
  148. foreach($ieAccounts as $k => $v) {
  149. $disabled = (!$v->is_personal) ? "DISABLED" : "";
  150. $group = (!$v->is_personal) ? $app_strings['LBL_EMAIL_GROUP']."." : "";
  151. $ieAccountsOptions .= "<option value='{$v->id}' $disabled>{$group}{$v->name}</option>\n";
  152. }
  153. $this->smarty->assign('ieAccounts', $ieAccountsOptions);
  154. $this->smarty->assign('rollover', $this->rolloverStyle);
  155. $protocol = filterInboundEmailPopSelection($app_list_strings['dom_email_server_type']);
  156. $this->smarty->assign('PROTOCOL', get_select_options_with_id($protocol, ''));
  157. $this->smarty->assign('MAIL_SSL_OPTIONS', get_select_options_with_id($app_list_strings['email_settings_for_ssl'], ''));
  158. $this->smarty->assign('ie_mod_strings', return_module_language($current_language, 'InboundEmail'));
  159. $charsetSelectedValue = isset($emailSettings['defaultOutboundCharset']) ? $emailSettings['defaultOutboundCharset'] : false;
  160. if (!$charsetSelectedValue) {
  161. $charsetSelectedValue = $current_user->getPreference('default_export_charset', 'global');
  162. if (!$charsetSelectedValue) {
  163. $charsetSelectedValue = $locale->getPrecedentPreference('default_email_charset');
  164. }
  165. }
  166. $charset = array(
  167. 'options' => $locale->getCharsetSelect(),
  168. 'selected' => $charsetSelectedValue,
  169. );
  170. $this->smarty->assign('charset', $charset);
  171. $emailCheckInterval = array('options' => $app_strings['LBL_EMAIL_CHECK_INTERVAL_DOM'], 'selected' => $emailSettings['emailCheckInterval']);
  172. $this->smarty->assign('emailCheckInterval', $emailCheckInterval);
  173. $this->smarty->assign('attachmentsSearchOptions', $app_list_strings['checkbox_dom']);
  174. $this->smarty->assign('sendPlainTextChecked', ($emailSettings['sendPlainText'] == 1) ? 'CHECKED' : '');
  175. $this->smarty->assign('showNumInList', get_select_options_with_id($app_list_strings['email_settings_num_dom'], $emailSettings['showNumInList']));
  176. //// END USER SETTINGS
  177. ///////////////////////////////////////////////////////////////////////
  178. ///////////////////////////////////////////////////////////////////////
  179. //// SIGNATURES
  180. $prependSignature = ($current_user->getPreference('signature_prepend')) ? 'true' : 'false';
  181. $defsigID = $current_user->getPreference('signature_default');
  182. $this->smarty->assign('signatures', $current_user->getSignatures(false, $defsigID));
  183. $this->smarty->assign('signaturesSettings', $current_user->getSignatures(false, $defsigID, false));
  184. $signatureButtons = $current_user->getSignatureButtons('SUGAR.email2.settings.createSignature', !empty($defsigID));
  185. if (!empty($defsigID)) {
  186. $signatureButtons = $signatureButtons . '<span name="delete_sig" id="delete_sig" style="visibility:inherit;"><input class="button" onclick="javascript:SUGAR.email2.settings.deleteSignature();" value="'.$app_strings['LBL_EMAIL_DELETE'].'" type="button" tabindex="392">&nbsp;
  187. </span>';
  188. } else {
  189. $signatureButtons = $signatureButtons . '<span name="delete_sig" id="delete_sig" style="visibility:hidden;"><input class="button" onclick="javascript:SUGAR.email2.settings.deleteSignature();" value="'.$app_strings['LBL_EMAIL_DELETE'].'" type="button" tabindex="392">&nbsp;
  190. </span>';
  191. }
  192. $this->smarty->assign('signatureButtons', $signatureButtons);
  193. $this->smarty->assign('signaturePrepend', $prependSignature == 'true' ? 'CHECKED' : '');
  194. //// END SIGNATURES
  195. ///////////////////////////////////////////////////////////////////////
  196. ///////////////////////////////////////////////////////////////////////
  197. //// EMAIL TEMPLATES
  198. $email_templates_arr = $this->getEmailTemplatesArray();
  199. natcasesort($email_templates_arr);
  200. $this->smarty->assign('EMAIL_TEMPLATE_OPTIONS', get_select_options_with_id($email_templates_arr, ''));
  201. //// END EMAIL TEMPLATES
  202. ///////////////////////////////////////////////////////////////////////
  203. ///////////////////////////////////////////////////////////////////////
  204. //// FOLDERS & TreeView
  205. $this->smarty->assign('groupUserOptions', $ie->getGroupsWithSelectOptions(array('' => $app_strings['LBL_EMAIL_CREATE_NEW'])));
  206. $tree = $this->getMailboxNodes();
  207. // preloaded folder
  208. $preloadFolder = 'lazyLoadFolder = ';
  209. $focusFolderSerial = $current_user->getPreference('focusFolder', 'Emails');
  210. if(!empty($focusFolderSerial)) {
  211. $focusFolder = unserialize($focusFolderSerial);
  212. //$focusFolder['ieId'], $focusFolder['folder']
  213. $preloadFolder .= json_encode($focusFolder).";";
  214. } else {
  215. $preloadFolder .= "new Object();";
  216. }
  217. //// END FOLDERS
  218. ///////////////////////////////////////////////////////////////////////
  219. $out = "";
  220. $out .= $this->smarty->fetch("modules/Emails/templates/_baseEmail.tpl");
  221. $out .= $tree->generate_header();
  222. $out .= $tree->generateNodesNoInit(true, 'email2treeinit');
  223. $out .=<<<eoq
  224. <script type="text/javascript" language="javascript">
  225. var loader = new YAHOO.util.YUILoader({
  226. require : [
  227. "layout", "element", "tabview", "menu",
  228. "cookie", "sugarwidgets"
  229. ],
  230. loadOptional: true,
  231. skin: { base: 'blank', defaultSkin: '' },
  232. onSuccess: email2init,
  233. allowRollup: true,
  234. base: "include/javascript/yui/build/"
  235. });
  236. loader.addModule({
  237. name :"sugarwidgets",
  238. type : "js",
  239. fullpath: "include/javascript/sugarwidgets/SugarYUIWidgets.js",
  240. varName: "YAHOO.SUGAR",
  241. requires: ["datatable", "dragdrop", "treeview", "tabview", "calendar"]
  242. });
  243. loader.insert();
  244. {$preloadFolder};
  245. </script>
  246. eoq;
  247. return $out;
  248. }
  249. /**
  250. * Generate the frame needed for the quick compose email UI. This frame is loaded dynamically
  251. * by an ajax call.
  252. *
  253. * @return JSON An object containing html markup and js script variables.
  254. */
  255. function displayQuickComposeEmailFrame()
  256. {
  257. $this->preflightUserCache();
  258. $this->_generateComposeConfigData('email_compose_light');
  259. $javascriptOut = $this->smarty->fetch("modules/Emails/templates/_baseConfigData.tpl");
  260. $divOut = $this->smarty->fetch("modules/Emails/templates/overlay.tpl");
  261. $divOut .= $this->smarty->fetch("modules/Emails/templates/addressSearchContent.tpl");
  262. $outData = array('jsData' => $javascriptOut,'divData'=> $divOut);
  263. $out = json_encode($outData);
  264. return $out;
  265. }
  266. /**
  267. * Load the modules from the metadata file and include in a custom one if it exists
  268. *
  269. * @return array
  270. */
  271. protected function _loadQuickCreateModules()
  272. {
  273. $QCAvailableModules = array();
  274. $QCModules = array();
  275. include('modules/Emails/metadata/qcmodulesdefs.php');
  276. if (file_exists('custom/modules/Emails/metadata/qcmodulesdefs.php')) {
  277. include('custom/modules/Emails/metadata/qcmodulesdefs.php');
  278. }
  279. foreach($QCModules as $module) {
  280. $seed = SugarModule::get($module)->loadBean();
  281. if ( ( $seed instanceOf SugarBean ) && $seed->ACLAccess('edit') ) {
  282. $QCAvailableModules[] = $module;
  283. }
  284. }
  285. return $QCAvailableModules;
  286. }
  287. /**
  288. * Given an email link url (eg. index.php?action=Compose&parent_type=Contacts...) break up the
  289. * request components and create a compose package that can be used by the quick compose UI. The
  290. * result is typically passed into the js call SUGAR.quickCompose.init which initalizes the quick compose
  291. * UI.
  292. *
  293. * @param String $emailLinkUrl
  294. * @return JSON Object containing the composePackage and full link url
  295. */
  296. function generateComposePackageForQuickCreateFromComposeUrl($emailLinkUrl, $lazyLoad=false)
  297. {
  298. $composeData = explode("&",$emailLinkUrl);
  299. $a_composeData = array();
  300. foreach ($composeData as $singleRequest)
  301. {
  302. $tmp = explode("=",$singleRequest);
  303. $a_composeData[$tmp[0]] = urldecode($tmp[1]);
  304. }
  305. return $this->generateComposePackageForQuickCreate($a_composeData,$emailLinkUrl, $lazyLoad);
  306. }
  307. /**
  308. * Generate the composePackage for the quick compose email UI. The package contains
  309. * key/value pairs generated by the Compose.php file which are then set into the
  310. * quick compose email UI (eg. to addr, parent id, parent type, etc)
  311. *
  312. * @param Array $composeData Associative array read and processed by generateComposeDataPackage.
  313. * @param String $fullLinkUrl A link that contains all pertinant information so the user can be
  314. * directed to the full compose screen if needed
  315. * @return JSON Object containg composePackage and fullLinkUrl
  316. */
  317. function generateComposePackageForQuickCreate($composeData,$fullLinkUrl, $lazyLoad=false)
  318. {
  319. $_REQUEST['forQuickCreate'] = true;
  320. if(!$lazyLoad){
  321. require_once('modules/Emails/Compose.php');
  322. $composePackage = generateComposeDataPackage($composeData,FALSE);
  323. }else{
  324. $composePackage = $composeData;
  325. }
  326. // JSON object is passed into the function defined within the a href onclick event
  327. // which is delimeted by '. Need to escape all single quotes and &, <, >
  328. // but not double quotes since json would escape them
  329. foreach ($composePackage as $key => $singleCompose)
  330. {
  331. if (is_string($singleCompose))
  332. $composePackage[$key] = str_replace("&nbsp;", " ", from_html($singleCompose));
  333. }
  334. $quickComposeOptions = array('fullComposeUrl' => $fullLinkUrl,'composePackage' => $composePackage);
  335. $j_quickComposeOptions = JSON::encode($quickComposeOptions, false ,true);
  336. return $j_quickComposeOptions;
  337. }
  338. /**
  339. * Generate the config data needed for the Full Compose UI and the Quick Compose UI. The set of config data
  340. * returned is the minimum set needed by the quick compose UI.
  341. *
  342. * @param String $type Drives which tinyMCE options will be included.
  343. */
  344. function _generateComposeConfigData($type = "email_compose_light" )
  345. {
  346. global $app_list_strings,$current_user, $app_strings, $mod_strings,$current_language,$locale;
  347. //Link drop-downs
  348. $parent_types = $app_list_strings['record_type_display'];
  349. $disabled_parent_types = ACLController::disabledModuleList($parent_types, false, 'list');
  350. foreach($disabled_parent_types as $disabled_parent_type) {
  351. unset($parent_types[$disabled_parent_type]);
  352. }
  353. asort($parent_types);
  354. $linkBeans = json_encode(get_select_options_with_id($parent_types, ''));
  355. //TinyMCE Config
  356. require_once("include/SugarTinyMCE.php");
  357. $tiny = new SugarTinyMCE();
  358. $tinyConf = $tiny->getConfig($type);
  359. //Generate Language Packs
  360. $lang = "var app_strings = new Object();\n";
  361. foreach($app_strings as $k => $v) {
  362. if(strpos($k, 'LBL_EMAIL_') !== false) {
  363. $lang .= "app_strings.{$k} = '{$v}';\n";
  364. }
  365. }
  366. //Get the email mod strings but don't use the global variable as this may be overridden by
  367. //other modules when the quick create is rendered.
  368. $email_mod_strings = return_module_language($current_language,'Emails');
  369. $modStrings = "var mod_strings = new Object();\n";
  370. foreach($email_mod_strings as $k => $v) {
  371. $v = str_replace("'", "\'", $v);
  372. $modStrings .= "mod_strings.{$k} = '{$v}';\n";
  373. }
  374. $lang .= "\n\n{$modStrings}\n";
  375. //Grab the Inboundemail language pack
  376. $ieModStrings = "var ie_mod_strings = new Object();\n";
  377. $ie_mod_strings = return_module_language($current_language,'InboundEmail');
  378. foreach($ie_mod_strings as $k => $v) {
  379. $v = str_replace("'", "\'", $v);
  380. $ieModStrings .= "ie_mod_strings.{$k} = '{$v}';\n";
  381. }
  382. $lang .= "\n\n{$ieModStrings}\n";
  383. $this->smarty->assign('linkBeans', $linkBeans);
  384. $this->smarty->assign('linkBeansOptions', $parent_types);
  385. $this->smarty->assign('tinyMCE', $tinyConf);
  386. $this->smarty->assign('lang', $lang);
  387. $this->smarty->assign('app_strings', $app_strings);
  388. $this->smarty->assign('mod_strings', $email_mod_strings);
  389. $ie1 = new InboundEmail();
  390. //Signatures
  391. $defsigID = $current_user->getPreference('signature_default');
  392. $defaultSignature = $current_user->getDefaultSignature();
  393. $sigJson = !empty($defaultSignature) ? json_encode(array($defaultSignature['id'] => from_html($defaultSignature['signature_html']))) : "new Object()";
  394. $this->smarty->assign('defaultSignature', $sigJson);
  395. $this->smarty->assign('signatureDefaultId', (isset($defaultSignature['id'])) ? $defaultSignature['id'] : "");
  396. //User Preferences
  397. $this->smarty->assign('userPrefs', json_encode($this->getUserPrefsJS()));
  398. //Get the users default outbound id
  399. $defaultOutID = $ie1->getUsersDefaultOutboundServerId($current_user);
  400. $this->smarty->assign('defaultOutID', $defaultOutID);
  401. //Character Set
  402. $charsets = json_encode($locale->getCharsetSelect());
  403. $this->smarty->assign('emailCharsets', $charsets);
  404. //Relateable List of People for address book search
  405. //#20776 jchi
  406. $peopleTables = array("users",
  407. "contacts",
  408. "leads",
  409. "prospects",
  410. "accounts");
  411. $filterPeopleTables = array();
  412. global $app_list_strings, $app_strings;
  413. $filterPeopleTables['LBL_DROPDOWN_LIST_ALL'] = $app_strings['LBL_DROPDOWN_LIST_ALL'];
  414. foreach($peopleTables as $table) {
  415. $module = ucfirst($table);
  416. $class = substr($module, 0, strlen($module) - 1);
  417. require_once("modules/{$module}/{$class}.php");
  418. $person = new $class();
  419. if (!$person->ACLAccess('list')) continue;
  420. $filterPeopleTables[$person->table_name] = $app_list_strings['moduleList'][$person->module_dir];
  421. }
  422. $this->smarty->assign('listOfPersons' , get_select_options_with_id($filterPeopleTables,''));
  423. }
  424. //// END CORE
  425. ///////////////////////////////////////////////////////////////////////////
  426. ///////////////////////////////////////////////////////////////////////////
  427. //// ADDRESS BOOK
  428. /**
  429. * Retrieves all relationship metadata for a user's address book
  430. * @return array
  431. */
  432. function getContacts() {
  433. global $current_user;
  434. $q = "SELECT * FROM address_book WHERE assigned_user_id = '{$current_user->id}' ORDER BY bean DESC";
  435. $r = $this->db->query($q);
  436. $ret = array();
  437. while($a = $this->db->fetchByAssoc($r)) {
  438. $ret[$a['bean_id']] = array(
  439. 'id' => $a['bean_id'],
  440. 'module' => $a['bean'],
  441. );
  442. }
  443. return $ret;
  444. }
  445. /**
  446. * Saves changes to a user's address book
  447. * @param array contacts
  448. */
  449. function setContacts($contacts) {
  450. global $current_user;
  451. $oldContacts = $this->getContacts();
  452. foreach($contacts as $cid => $contact) {
  453. if(!in_array($contact['id'], $oldContacts)) {
  454. $q = "INSERT INTO address_book (assigned_user_id, bean, bean_id) VALUES ('{$current_user->id}', '{$contact['module']}', '{$contact['id']}')";
  455. $r = $this->db->query($q, true);
  456. }
  457. }
  458. }
  459. /**
  460. * Removes contacts from the user's address book
  461. * @param array ids
  462. */
  463. function removeContacts($ids) {
  464. global $current_user;
  465. $concat = "";
  466. foreach($ids as $id) {
  467. if(!empty($concat))
  468. $concat .= ", ";
  469. $concat .= "'{$id}'";
  470. }
  471. $q = "DELETE FROM address_book WHERE assigned_user_id = '{$current_user->id}' AND bean_id IN ({$concat})";
  472. $r = $this->db->query($q);
  473. }
  474. /**
  475. * saves editted Contact info
  476. * @param string $str JSON serialized object
  477. */
  478. function saveContactEdit($str) {
  479. $json = getJSONobj();
  480. $str = from_html($str);
  481. $obj = $json->decode($str);
  482. $contact = new Contact();
  483. $contact->retrieve($obj['contact_id']);
  484. $contact->first_name = $obj['contact_first_name'];
  485. $contact->last_name = $obj['contact_last_name'];
  486. $contact->save();
  487. // handle email address changes
  488. $addresses = array();
  489. foreach($obj as $k => $req) {
  490. if(strpos($k, 'emailAddress') !== false) {
  491. $addresses[$k] = $req;
  492. }
  493. }
  494. // prefill some REQUEST vars for emailAddress save
  495. $_REQUEST['emailAddressOptOutFlag'] = $obj['optOut'];
  496. $_REQUEST['emailAddressInvalidFlag'] = $obj['invalid'];
  497. $contact->emailAddress->save($obj['contact_id'], 'Contacts', $addresses, $obj['primary'], '');
  498. }
  499. /**
  500. * Prepares the Edit Contact mini-form via template assignment
  501. * @param string id ID of contact in question
  502. * @param string module Module in focus
  503. * @return array
  504. */
  505. function getEditContact($id, $module) {
  506. global $app_strings;
  507. if(!class_exists("Contact")) {
  508. }
  509. $contact = new Contact();
  510. $contact->retrieve($_REQUEST['id']);
  511. $ret = array();
  512. if($contact->ACLAccess('edit')) {
  513. $contactMeta = array();
  514. $contactMeta['id'] = $contact->id;
  515. $contactMeta['module'] = $contact->module_dir;
  516. $contactMeta['first_name'] = $contact->first_name;
  517. $contactMeta['last_name'] = $contact->last_name;
  518. $this->smarty->assign("app_strings", $app_strings);
  519. $this->smarty->assign("contact_strings", return_module_language($_SESSION['authenticated_user_language'], 'Contacts'));
  520. $this->smarty->assign("contact", $contactMeta);
  521. $ea = new SugarEmailAddress();
  522. $newEmail = $ea->getEmailAddressWidgetEditView($id, $module, true);
  523. $this->smarty->assign("emailWidget", $newEmail['html']);
  524. $ret['form'] = $this->smarty->fetch("modules/Emails/templates/editContact.tpl");
  525. $ret['prefillData'] = $newEmail['prefillData'];
  526. } else {
  527. $id = "";
  528. $ret['form'] = $app_strings['LBL_EMAIL_ERROR_NO_ACCESS'];
  529. $ret['prefillData'] = '{}';
  530. }
  531. $ret['id'] = $id;
  532. $ret['contactName'] = $contact->full_name;
  533. return $ret;
  534. }
  535. /**
  536. * Retrieves a concatenated list of contacts, those with assigned_user_id = user's id and those in the address_book
  537. * table
  538. * @param array $contacts Array of contact types -> IDs
  539. * @param object $user User in focus
  540. * @return array
  541. */
  542. function getUserContacts($contacts, $user=null) {
  543. global $current_user;
  544. global $locale;
  545. if(empty($user)) {
  546. $user = $current_user;
  547. }
  548. $emailAddress = new SugarEmailAddress();
  549. $ret = array();
  550. $union = '';
  551. $modules = array();
  552. foreach($contacts as $contact) {
  553. if(!isset($modules[$contact['module']])) {
  554. $modules[$contact['module']] = array();
  555. }
  556. $modules[$contact['module']][] = $contact;
  557. }
  558. foreach($modules as $module => $contacts) {
  559. if(!empty($union)) {
  560. $union .= " UNION ALL ";
  561. }
  562. $table = strtolower($module);
  563. $idsSerial = '';
  564. foreach($contacts as $contact) {
  565. if(!empty($idsSerial)) {
  566. $idsSerial .= ",";
  567. }
  568. $idsSerial .= "'{$contact['id']}'";
  569. }
  570. $union .= "(SELECT id, first_name, last_name, title, '{$module}' module FROM {$table} WHERE id IN({$idsSerial}) AND deleted = 0 )";
  571. }
  572. if(!empty($union)) {
  573. $union .= " ORDER BY last_name";
  574. }
  575. $r = $user->db->query($union);
  576. //_pp($union);
  577. while($a = $user->db->fetchByAssoc($r)) {
  578. $c = array();
  579. $c['name'] = $locale->getLocaleFormattedName($a['first_name'], "<b>{$a['last_name']}</b>", '', $a['title'], '', $user);
  580. $c['id'] = $a['id'];
  581. $c['module'] = $a['module'];
  582. $c['email'] = $emailAddress->getAddressesByGUID($a['id'], $a['module']);
  583. $ret[$a['id']] = $c;
  584. }
  585. return $ret;
  586. }
  587. //// END ADDRESS BOOK
  588. ///////////////////////////////////////////////////////////////////////////
  589. ///////////////////////////////////////////////////////////////////////////
  590. //// EMAIL 2.0 Preferences
  591. function getUserPrefsJS() {
  592. global $current_user;
  593. global $locale;
  594. // sort order per mailbox view
  595. $sortSerial = $current_user->getPreference('folderSortOrder', 'Emails');
  596. $sortArray = array();
  597. if(!empty($sortSerial)) {
  598. $sortArray = unserialize($sortSerial);
  599. }
  600. // treeview collapsed/open states
  601. $folderStateSerial = $current_user->getPreference('folderOpenState', 'Emails');
  602. $folderStates = array();
  603. if(!empty($folderStateSerial)) {
  604. $folderStates = unserialize($folderStateSerial);
  605. }
  606. // subscribed accounts
  607. $showFolders = unserialize(base64_decode($current_user->getPreference('showFolders', 'Emails')));
  608. // general settings
  609. $emailSettings = $current_user->getPreference('emailSettings', 'Emails');
  610. if(empty($emailSettings)) {
  611. $emailSettings = array();
  612. $emailSettings['emailCheckInterval'] = -1;
  613. $emailSettings['autoImport'] = '';
  614. $emailSettings['alwaysSaveOutbound'] = '1';
  615. $emailSettings['sendPlainText'] = '';
  616. $emailSettings['defaultOutboundCharset'] = $GLOBALS['sugar_config']['default_email_charset'];
  617. $emailSettings['showNumInList'] = 20;
  618. }
  619. // focus folder
  620. $focusFolder = $current_user->getPreference('focusFolder', 'Emails');
  621. $focusFolder = !empty($focusFolder) ? unserialize($focusFolder) : array();
  622. // unread only flag
  623. $showUnreadOnly = $current_user->getPreference('showUnreadOnly', 'Emails');
  624. $listViewSort = array(
  625. "sortBy" => 'date',
  626. "sortDirection" => 'DESC',
  627. );
  628. // signature prefs
  629. $signaturePrepend = $current_user->getPreference('signature_prepend') ? 'true' : 'false';
  630. $signatureDefault = $current_user->getPreference('signature_default');
  631. $signatures = array(
  632. 'signature_prepend' => $signaturePrepend,
  633. 'signature_default' => $signatureDefault
  634. );
  635. // current_user
  636. $user = array(
  637. 'emailAddresses' => $current_user->emailAddress->getAddressesByGUID($current_user->id, 'Users'),
  638. 'full_name' => from_html($current_user->full_name),
  639. );
  640. $userPreferences = array();
  641. $userPreferences['sort'] = $sortArray;
  642. $userPreferences['folderStates'] = $folderStates;
  643. $userPreferences['showFolders'] = $showFolders;
  644. $userPreferences['emailSettings'] = $emailSettings;
  645. $userPreferences['focusFolder'] = $focusFolder;
  646. $userPreferences['showUnreadOnly'] = $showUnreadOnly;
  647. $userPreferences['listViewSort'] = $listViewSort;
  648. $userPreferences['signatures'] = $signatures;
  649. $userPreferences['current_user'] = $user;
  650. return $userPreferences;
  651. }
  652. ///////////////////////////////////////////////////////////////////////////
  653. //// FOLDER FUNCTIONS
  654. /**
  655. * Creates a new Sugar folder
  656. * @param string $nodeLabel New sugar folder name
  657. * @param string $parentLabel Parent folder name
  658. */
  659. function saveNewFolder($nodeLabel, $parentId, $isGroup=0) {
  660. global $current_user;
  661. $this->folder->name = $nodeLabel;
  662. $this->folder->is_group = $isGroup;
  663. $this->folder->parent_folder = ($parentId == 'Home') ? "" : $parentId;
  664. $this->folder->has_child = 0;
  665. $this->folder->created_by = $current_user->id;
  666. $this->folder->modified_by = $current_user->id;
  667. $this->folder->date_modified = $this->folder->date_created = TimeDate::getInstance()->nowDb();
  668. $this->folder->save();
  669. return array(
  670. 'action' => 'newFolderSave',
  671. 'id' => $this->folder->id,
  672. 'name' => $this->folder->name,
  673. 'is_group' => $this->folder->is_group,
  674. 'is_dynamic' => $this->folder->is_dynamic
  675. );
  676. }
  677. /**
  678. * Saves user sort prefernces
  679. */
  680. function saveListViewSortOrder($ieId, $focusFolder, $sortBy, $sortDir) {
  681. global $current_user;
  682. $sortArray = array();
  683. $sortSerial = $current_user->getPreference('folderSortOrder', 'Emails');
  684. if(!empty($sortSerial)) {
  685. $sortArray = unserialize($sortSerial);
  686. }
  687. $sortArray[$ieId][$focusFolder]['current']['sort'] = $sortBy;
  688. $sortArray[$ieId][$focusFolder]['current']['direction'] = $sortDir;
  689. $sortSerial = serialize($sortArray);
  690. $current_user->setPreference('folderSortOrder', $sortSerial, '', 'Emails');
  691. }
  692. /**
  693. * Stickies folder collapse/open state
  694. */
  695. function saveFolderOpenState($focusFolder, $focusFolderOpen) {
  696. global $current_user;
  697. $folderStateSerial = $current_user->getPreference('folderOpenState', 'Emails');
  698. $folderStates = array();
  699. if(!empty($folderStateSerial)) {
  700. $folderStates = unserialize($folderStateSerial);
  701. }
  702. $folderStates[$focusFolder] = $focusFolderOpen;
  703. $newFolderStateSerial = serialize($folderStates);
  704. $current_user->setPreference('folderOpenState', $newFolderStateSerial, '', 'Emails');
  705. }
  706. /**
  707. * saves a folder's view state
  708. */
  709. function saveListView($ieId, $folder) {
  710. global $current_user;
  711. $saveState = array();
  712. $saveState['ieId'] = $ieId;
  713. $saveState['folder'] = $folder;
  714. $saveStateSerial = serialize($saveState);
  715. $current_user->setPreference('focusFolder', $saveStateSerial, '', 'Emails');
  716. }
  717. /**
  718. * Generates cache folder structure
  719. */
  720. function preflightEmailCache($cacheRoot) {
  721. // base
  722. if(!file_exists($cacheRoot))
  723. mkdir_recursive(clean_path($cacheRoot));
  724. // folders
  725. if(!file_exists($cacheRoot."/folders"))
  726. mkdir_recursive(clean_path("{$cacheRoot}/folders"));
  727. // messages
  728. if(!file_exists($cacheRoot."/messages"))
  729. mkdir_recursive(clean_path("{$cacheRoot}/messages"));
  730. // attachments
  731. if(!file_exists($cacheRoot."/attachments"))
  732. mkdir_recursive(clean_path("{$cacheRoot}/attachments"));
  733. }
  734. function deleteEmailCacheForFolders($cacheRoot) {
  735. $filePath = $cacheRoot."/folders/folders.php";
  736. if (file_exists($filePath)) {
  737. unlink($filePath);
  738. }
  739. }
  740. ///////////////////////////////////////////////////////////////////////////
  741. //// IMAP FUNCTIONS
  742. /**
  743. * Identifies subscribed mailboxes and empties the trash
  744. * @param object $ie InboundEmail
  745. */
  746. function emptyTrash(&$ie) {
  747. global $current_user;
  748. $showFolders = unserialize(base64_decode($current_user->getPreference('showFolders', 'Emails')));
  749. if(is_array($showFolders)) {
  750. foreach($showFolders as $ieId) {
  751. if(!empty($ieId)) {
  752. $ie->retrieve($ieId);
  753. $ie->emptyTrash();
  754. }
  755. }
  756. }
  757. }
  758. /**
  759. * returns an array of nodes that correspond to IMAP mailboxes.
  760. * @param bool $forceRefresh
  761. * @return object TreeView object
  762. */
  763. function getMailboxNodes() {
  764. global $sugar_config;
  765. global $current_user;
  766. global $app_strings;
  767. $tree = new Tree("frameFolders");
  768. $tree->tree_style= 'include/ytree/TreeView/css/check/tree.css';
  769. $nodes = array();
  770. $ie = new InboundEmail();
  771. $refreshOffset = $this->cacheTimeouts['folders']; // 5 mins. this will be set via user prefs
  772. $rootNode = new ExtNode($app_strings['LBL_EMAIL_HOME_FOLDER'], $app_strings['LBL_EMAIL_HOME_FOLDER']);
  773. $rootNode->dynamicloadfunction = '';
  774. $rootNode->expanded = true;
  775. $rootNode->dynamic_load = true;
  776. $showFolders = unserialize(base64_decode($current_user->getPreference('showFolders', 'Emails')));
  777. if(empty($showFolders)) {
  778. $showFolders = array();
  779. }
  780. // INBOX NODES
  781. if($current_user->hasPersonalEmail()) {
  782. $personals = $ie->retrieveByGroupId($current_user->id);
  783. foreach($personals as $k => $personalAccount) {
  784. if(in_array($personalAccount->id, $showFolders)) {
  785. // check for cache value
  786. $cacheRoot = "{$sugar_config['cache_dir']}modules/Emails/{$personalAccount->id}";
  787. $this->preflightEmailCache($cacheRoot);
  788. if($this->validCacheFileExists($personalAccount->id, 'folders', "folders.php")) {
  789. $mailboxes = $this->getMailBoxesFromCacheValue($personalAccount);
  790. } else {
  791. $mailboxes = $personalAccount->getMailboxes();
  792. }
  793. $acctNode = new ExtNode('Home::' . $personalAccount->name, $personalAccount->name);
  794. $acctNode->dynamicloadfunction = '';
  795. $acctNode->expanded = false;
  796. $acctNode->set_property('cls', 'ieFolder');
  797. $acctNode->set_property('ieId', $personalAccount->id);
  798. $acctNode->set_property('protocol', $personalAccount->protocol);
  799. if(array_key_exists('Home::'.$personalAccount->name, $this->folderStates)) {
  800. if($this->folderStates['Home::'.$personalAccount->name] == 'open') {
  801. $acctNode->expanded = true;
  802. }
  803. }
  804. $acctNode->dynamic_load = true;
  805. $nodePath = $acctNode->_properties['id'];
  806. foreach($mailboxes as $k => $mbox) {
  807. $acctNode->add_node($this->buildTreeNode($k, $k, $mbox, $personalAccount->id,
  808. $nodePath, false, $personalAccount));
  809. }
  810. $rootNode->add_node($acctNode);
  811. }
  812. }
  813. }
  814. // GROUP INBOX NODES
  815. $beans = $ie->retrieveAllByGroupId($current_user->id, false);
  816. foreach($beans as $k => $groupAccount) {
  817. if(in_array($groupAccount->id, $showFolders)) {
  818. // check for cache value
  819. $cacheRoot = "{$sugar_config['cache_dir']}modules/Emails/{$groupAccount->id}";
  820. $this->preflightEmailCache($cacheRoot);
  821. //$groupAccount->connectMailserver();
  822. if($this->validCacheFileExists($groupAccount->id, 'folders', "folders.php")) {
  823. $mailboxes = $this->getMailBoxesFromCacheValue($groupAccount);
  824. } else {
  825. $mailboxes = $groupAccount->getMailBoxesForGroupAccount();
  826. }
  827. $acctNode = new ExtNode($groupAccount->name, "group.{$groupAccount->name}");
  828. $acctNode->dynamicloadfunction = '';
  829. $acctNode->expanded = false;
  830. $acctNode->set_property('isGroup', 'true');
  831. $acctNode->set_property('ieId', $groupAccount->id);
  832. $acctNode->set_property('protocol', $groupAccount->protocol);
  833. if(array_key_exists('Home::'.$groupAccount->name, $this->folderStates)) {
  834. if($this->folderStates['Home::'.$groupAccount->name] == 'open') {
  835. $acctNode->expanded = true;
  836. }
  837. }
  838. $acctNode->dynamic_load = true;
  839. $nodePath = $rootNode->_properties['id']."::".$acctNode->_properties['id'];
  840. foreach($mailboxes as $k => $mbox) {
  841. $acctNode->add_node($this->buildTreeNode($k, $k, $mbox, $groupAccount->id,
  842. $nodePath, true, $groupAccount));
  843. }
  844. $rootNode->add_node($acctNode);
  845. }
  846. }
  847. // SugarFolder nodes
  848. /* SugarFolders are built at onload when the UI renders */
  849. $tree->add_node($rootNode);
  850. return $tree;
  851. }
  852. function getMailBoxesFromCacheValue($mailAccount) {
  853. $foldersCache = $this->getCacheValue($mailAccount->id, 'folders', "folders.php", 'foldersCache');
  854. $mailboxes = $foldersCache['mailboxes'];
  855. $mailboxesArray = $mailAccount->generateFlatArrayFromMultiDimArray($mailboxes, $mailAccount->retrieveDelimiter());
  856. $mailAccount->saveMailBoxFolders($mailboxesArray);
  857. $this->deleteEmailCacheForFolders($cacheRoot);
  858. return $mailboxes;
  859. } // fn
  860. /**
  861. * Builds up a TreeView Node object
  862. * @param mixed
  863. * @param mixed
  864. * @param string
  865. * @param string ID of InboundEmail instance
  866. * @param string nodePath Serialized path from root node to current node
  867. * @param bool isGroup
  868. * @param bool forceRefresh
  869. * @return mixed
  870. */
  871. function buildTreeNode($key, $label, $mbox, $ieId, $nodePath, $isGroup, $ie) {
  872. global $sugar_config;
  873. // get unread counts
  874. $exMbox = explode("::", $nodePath);
  875. $unseen = 0;
  876. $GLOBALS['log']->debug("$key --- $nodePath::$label");
  877. if(count($exMbox) >= 2) {
  878. $mailbox = "";
  879. for($i=2; $i<count($exMbox); $i++) {
  880. if($mailbox != "") {
  881. $mailbox .= ".";
  882. }
  883. $mailbox .= "{$exMbox[$i]}";
  884. }
  885. $mailbox = substr($key, strpos($key, '.'));
  886. $unseen = $this->getUnreadCount($ie, $mailbox);
  887. if($unseen > 0) {
  888. //$label = " <span id='span{$ie->id}{$ie->mailbox}' style='font-weight:bold'>{$label} (<span id='span{$ie->id}{$ie->mailbox}nums'>{$unseen}</span>)</span>";
  889. }
  890. }
  891. $nodePath = $nodePath."::".$label;
  892. $node = new ExtNode($nodePath, $label);
  893. $node->dynamicloadfunction = '';
  894. $node->expanded = false;
  895. $node->set_property('labelStyle', "remoteFolder");
  896. if(array_key_exists($nodePath, $this->folderStates)) {
  897. if($this->folderStates[$nodePath] == 'open') {
  898. $node->expanded = true;
  899. }
  900. }
  901. $group = ($isGroup) ? 'true' : 'false';
  902. $node->dynamic_load = true;
  903. //$node->set_property('href', " SUGAR.email2.listView.populateListFrame(YAHOO.namespace('frameFolders').selectednode, '{$ieId}', 'false');");
  904. $node->set_property('isGroup', $group);
  905. $node->set_property('isDynamic', 'false');
  906. $node->set_property('ieId', $ieId);
  907. $node->set_property('mbox', $key);
  908. $node->set_property('unseen', $unseen);
  909. $node->set_property('cls', 'ieFolder');
  910. if(is_array($mbox)) {
  911. foreach($mbox as $k => $v) {
  912. $node->add_node($this->buildTreeNode("$key.$k", $k, $v, $ieId, $nodePath, $isGroup, $ie));
  913. }
  914. }
  915. return $node;
  916. }
  917. /**
  918. * Totals the unread emails
  919. */
  920. function getUnreadCount(&$ie, $mailbox) {
  921. global $sugar_config;
  922. $unseen = 0;
  923. // use cache
  924. return $ie->getCacheUnreadCount($mailbox);
  925. }
  926. ///////////////////////////////////////////////////////////////////////////
  927. //// DISPLAY CODE
  928. /**
  929. * Used exclusively by draft code. Returns Notes and Documents as attachments.
  930. * @param array $ret
  931. * @return array
  932. */
  933. function getDraftAttachments($ret) {
  934. global $db;
  935. // $ret['uid'] is the draft Email object's GUID
  936. $ret['attachments'] = array();
  937. $q = "SELECT id, filename FROM notes WHERE parent_id = '{$ret['uid']}' AND deleted = 0";
  938. $r = $db->query($q);
  939. while($a = $db->fetchByAssoc($r)) {
  940. $ret['attachments'][$a['id']] = array(
  941. 'id' => $a['id'],
  942. 'filename' => $a['filename'],
  943. );
  944. }
  945. return $ret;
  946. }
  947. function createCopyOfInboundAttachment($ie, $ret, $uid) {
  948. global $sugar_config;
  949. if ($ie->isPop3Protocol()) {
  950. // get the UIDL from database;
  951. $cachedUIDL = md5($uid);
  952. $cache = "{$sugar_config['cache_dir']}modules/Emails/{$ie->id}/messages/{$ie->mailbox}{$cachedUIDL}.php";
  953. } else {
  954. $cache = "{$sugar_config['cache_dir']}modules/Emails/{$ie->id}/messages/{$ie->mailbox}{$uid}.php";
  955. }
  956. if(file_exists($cache)) {
  957. include($cache); // profides $cacheFile
  958. $metaOut = unserialize($cacheFile['out']);
  959. $meta = $metaOut['meta']['email'];
  960. if (isset($meta['attachments'])) {
  961. $attachmentHtmlData = $meta['attachments'];
  962. $actualAttachmentInfo = array();
  963. $this->parseAttachmentInfo($actualAttachmentInfo, $attachmentHtmlData);
  964. if (sizeof($actualAttachmentInfo) > 0) {
  965. foreach($actualAttachmentInfo as $key => $value) {
  966. $attachmentid;
  967. $fileName;
  968. $datasplit = explode("&", $value);
  969. $attachmentIdArray = explode("=", $datasplit[0]);
  970. $attachmentid = $attachmentIdArray[1];
  971. $fileNameArray = explode("=", $datasplit[4]);
  972. $fileName = $fileNameArray[1];
  973. $guid = create_guid();
  974. //$destination = clean_path("{$this->userCacheDir}/{$guid}{$fileName}");
  975. $destination = clean_path("{$this->userCacheDir}/{$guid}");
  976. $attachmentFilePath = "{$sugar_config['cache_dir']}modules/Emails/{$ie->id}/attachments/{$attachmentid}";
  977. copy($attachmentFilePath, $destination);
  978. $ret['attachments'][$guid] = array();
  979. $ret['attachments'][$guid]['id'] = $guid . $fileName;
  980. $ret['attachments'][$guid]['filename'] = $fileName;
  981. } // for
  982. } // if
  983. } // if
  984. } // if
  985. return $ret;
  986. } // fn
  987. function parseAttachmentInfo(&$actualAttachmentInfo, $attachmentHtmlData) {
  988. $downLoadPHP = strpos($attachmentHtmlData, "index.php?entryPoint=download&");
  989. while ($downLoadPHP) {
  990. $attachmentHtmlData = substr($attachmentHtmlData, $downLoadPHP+30);
  991. $final = strpos($attachmentHtmlData, "\">");
  992. $actualAttachmentInfo[] = substr($attachmentHtmlData, 0, $final);
  993. $attachmentHtmlData = substr($attachmentHtmlData, $final);
  994. $downLoadPHP = strpos($attachmentHtmlData, "index.php?entryPoint=download&");
  995. } // while
  996. }
  997. /**
  998. * Renders the QuickCreate form from Smarty and returns HTML
  999. * @param array $vars request variable global
  1000. * @param object $email Fetched email object
  1001. * @param bool $addToAddressBook
  1002. * @return array
  1003. */
  1004. function getQuickCreateForm($vars, $email, $addToAddressBookButton=false) {
  1005. require_once("include/EditView/EditView2.php");
  1006. global $app_strings;
  1007. global $mod_strings;
  1008. global $current_user;
  1009. global $beanList;
  1010. global $beanFiles;
  1011. global $current_language;
  1012. //Setup the current module languge
  1013. $mod_strings = return_module_language($current_language, $_REQUEST['qc_module']);
  1014. $bean = $beanList[$_REQUEST['qc_module']];
  1015. $class = $beanFiles[$bean];
  1016. require_once($class);
  1017. $focus = new $bean();
  1018. $people = array(
  1019. 'Contact'
  1020. ,'Lead'
  1021. );
  1022. $emailAddress = array();
  1023. // people
  1024. if(in_array($bean, $people)) {
  1025. // lead specific
  1026. $focus->lead_source = 'Email';
  1027. $focus->lead_source_description = trim($email->name);
  1028. $from = (isset($email->from_name) && !empty($email->from_name)) ? $email->from_name : $email->from_addr;
  1029. if(isset($_REQUEST['sugarEmail']) && !empty($_REQUEST['sugarEmail']))
  1030. $from = (isset($email->from_name) && !empty($email->from_name)) ? $email->from_name : $email->from_addr_name;
  1031. $name = explode(" ", trim($from));
  1032. $address = trim(array_pop($name));
  1033. $address = str_replace(array("<",">","&lt;","&gt;"), "", $address);
  1034. $emailAddress[] = array(
  1035. 'email_address' => $address,
  1036. 'primary_address' => 1,
  1037. 'invalid_email' => 0,
  1038. 'opt_out' => 0,
  1039. 'reply_to_address' => 1
  1040. );
  1041. $focus->email1 = $address;
  1042. if(!empty($name)) {
  1043. $focus->last_name = trim(array_pop($name));
  1044. foreach($name as $first) {
  1045. if(!empty($focus->first_name)) {
  1046. $focus->first_name .= " ";
  1047. }
  1048. $focus->first_name .= trim($first);
  1049. }
  1050. }
  1051. } else {
  1052. // bugs, cases, tasks
  1053. $focus->name = trim($email->name);
  1054. }
  1055. $focus->description = trim(strip_tags($email->description));
  1056. $focus->assigned_user_id = $current_user->id;
  1057. $EditView = new EditView();
  1058. $EditView->ss = new Sugar_Smarty();
  1059. //MFH BUG#20283 - checks for custom quickcreate fields
  1060. $EditView->setup($_REQUEST['qc_module'], $focus, 'custom/modules/'.$focus->module_dir.'/metadata/editviewdefs.php', 'include/EditView/EditView.tpl');
  1061. $EditView->process();
  1062. $EditView->render();
  1063. $EditView->defs['templateMeta']['form']['buttons'] = array(
  1064. 'email2save' => array(
  1065. 'id' => 'e2AjaxSave',
  1066. 'customCode' => '<input type="button" class="button" value=" '.$app_strings['LBL_SAVE_BUTTON_LABEL']
  1067. . ' " onclick="SUGAR.email2.detailView.saveQuickCreate(false);" />'
  1068. ),
  1069. 'email2saveandreply' => array(
  1070. 'id' => 'e2SaveAndReply',
  1071. 'customCode' => '<input type="button" class="button" value=" '.$app_strings['LBL_EMAIL_SAVE_AND_REPLY']
  1072. . ' " onclick="SUGAR.email2.detailView.saveQuickCreate(\'reply\');" />'
  1073. ),
  1074. 'email2cancel' => array(
  1075. 'id' => 'e2cancel',
  1076. 'customCode' => '<input type="button" class="button" value=" '.$app_strings['LBL_EMAIL_CANCEL']
  1077. . ' " onclick="SUGAR.email2.detailView.quickCreateDialog.hide();" />'
  1078. )
  1079. );
  1080. if($addToAddressBookButton) {
  1081. $EditView->defs['templateMeta']['form']['buttons']['email2saveAddToAddressBook'] = array(
  1082. 'id' => 'e2addToAddressBook',
  1083. 'customCode' => '<input type="button" class="button" value=" '.$app_strings['LBL_EMAIL_ADDRESS_BOOK_SAVE_AND_ADD']
  1084. . ' " onclick="SUGAR.email2.detailView.saveQuickCreate(true);" />'
  1085. );
  1086. }
  1087. //Get the module language for javascript
  1088. if(!is_file($GLOBALS['sugar_config']['cache_dir'] . 'jsLanguage/' . $_REQUEST['qc_module'] . '/' . $GLOBALS['current_language'] . '.js')) {
  1089. require_once('include/language/jsLanguage.php');
  1090. jsLanguage::createModuleStringsCache($_REQUEST['qc_module'], $GLOBALS['current_language']);
  1091. }
  1092. $jsLanguage = '<script type="text/javascript" src="' . $GLOBALS['sugar_config']['cache_dir'] . 'jsLanguage/'
  1093. . $_REQUEST['qc_module'] . '/' . $GLOBALS['current_language'] . '.js?s=' . $GLOBALS['sugar_version'] . '&c='
  1094. . $GLOBALS['sugar_config']['js_custom_version'] . '&j=' . $GLOBALS['sugar_config']['js_lang_version'] . '"></script>';
  1095. $EditView->view = 'EmailQCView';
  1096. $EditView->defs['templateMeta']['form']['headerTpl'] = 'include/EditView/header.tpl';
  1097. $EditView->defs['templateMeta']['form']['footerTpl'] = 'include/EditView/footer.tpl';
  1098. $meta = array();
  1099. $meta['html'] = $jsLanguage . $EditView->display(false, true);
  1100. $meta['html'] = str_replace("src='include/SugarEmailAddress/SugarEmailAddress.js?s={$GLOBALS['js_version_key']}&c={$GLOBALS['sugar_config']['js_custom_version']}'", '', $meta['html']);
  1101. $meta['emailAddress'] = $emailAddress;
  1102. $mod_strings = return_module_language($current_language, 'Emails');
  1103. return $meta;
  1104. }
  1105. /**
  1106. * Renders the Import form from Smarty and returns HTML
  1107. * @param array $vars request variable global
  1108. * @param object $email Fetched email object
  1109. * @param bool $addToAddressBook
  1110. * @return array
  1111. */
  1112. function getImportForm($vars, $email, $formName = 'ImportEditView') {
  1113. require_once("include/EditView/EditView2.php");
  1114. require_once("include/TemplateHandler/TemplateHandler.php");
  1115. require_once('include/QuickSearchDefaults.php');
  1116. $qsd = new QuickSearchDefaults();
  1117. $qsd->setFormName($formName);
  1118. global $app_strings;
  1119. global $current_user;
  1120. global $app_list_strings;
  1121. $sqs_objects = array(
  1122. "{$formName}_parent_name" => $qsd->getQSParent(),
  1123. );
  1124. $smarty = new Sugar_Smarty();
  1125. $smarty->assign("APP",$app_strings);
  1126. $smarty->assign('formName',$formName);
  1127. $showAssignTo = false;
  1128. if (!isset($vars['showAssignTo']) || $vars['showAssignTo'] == true) {
  1129. $showAssignTo = true;
  1130. } // if
  1131. if ($showAssignTo) {
  1132. if(empty($email->assigned_user_id) && empty($email->id))
  1133. $email->assigned_user_id = $current_user->id;
  1134. if(empty($email->assigned_name) && empty($email->id))
  1135. $email->assigned_user_name = $current_user->user_name;
  1136. $sqs_objects["{$formName}_assigned_user_name"] = $qsd->getQSUser();
  1137. }
  1138. $smarty->assign("showAssignedTo",$showAssignTo);
  1139. $showDelete = false;
  1140. if (!isset($vars['showDelete']) || $vars['showDelete'] == true) {
  1141. $showDelete = true;
  1142. }
  1143. $smarty->assign("showDelete",$showDelete);
  1144. $smarty->assign("userId",$email->assigned_user_id);
  1145. $smarty->assign("userName",$email->assigned_user_name);
  1146. $parent_types = $app_list_strings['record_type_display'];
  1147. $smarty->assign('parentOptions', get_select_options_with_id($parent_types, $email->parent_type));
  1148. $quicksearch_js = '<script type="text/javascript" language="javascript">sqs_objects = ' . json_encode($sqs_objects) . '</script>';
  1149. $smarty->assign('SQS', $quicksearch_js);
  1150. $meta = array();
  1151. $meta['html'] = $smarty->fetch("modules/Emails/templates/importRelate.tpl");
  1152. return $meta;
  1153. }
  1154. /**
  1155. * This function returns the detail view for email in new 2.0 interface
  1156. *
  1157. */
  1158. function getDetailViewForEmail2($emailId) {
  1159. require_once('include/DetailView/DetailView…

Large files files are truncated, but you can click here to view the full file