PageRenderTime 48ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/modules/MailManager/src/controllers/RelationController.php

https://bitbucket.org/jhunsinfotech/blue-blues
PHP | 406 lines | 271 code | 58 blank | 77 comment | 66 complexity | 1deddfff7f91b72c1843fbdcd0312e82 MD5 | raw file
Possible License(s): LGPL-2.1, GPL-2.0, LGPL-3.0
  1. <?php
  2. /*+**********************************************************************************
  3. * The contents of this file are subject to the vtiger CRM Public License Version 1.1
  4. * ("License"); You may not use this file except in compliance with the License
  5. * The Original Code is: vtiger CRM Open Source
  6. * The Initial Developer of the Original Code is vtiger.
  7. * Portions created by vtiger are Copyright (C) vtiger.
  8. * All Rights Reserved.
  9. ************************************************************************************/
  10. include_once 'include/Webservices/DescribeObject.php';
  11. include_once 'include/Webservices/Query.php';
  12. require_once 'include/utils/utils.php';
  13. include_once 'modules/Settings/MailScanner/core/MailScannerAction.php';
  14. include_once 'modules/Settings/MailScanner/core/MailAttachmentMIME.php';
  15. require_once dirname(__FILE__) . '/RelationControllerAction.php';
  16. /**
  17. * Class used to manage the emails relationship with vtiger records
  18. */
  19. class MailManager_RelationController extends MailManager_Controller {
  20. /**
  21. * Used to check the MailBox connection
  22. * @var Boolean
  23. */
  24. protected $skipConnection = false;
  25. /** To avoid working with mailbox */
  26. protected function getMailboxModel() {
  27. if ($this->skipConnection) return false;
  28. return parent::getMailboxModel();
  29. }
  30. /**
  31. * List of modules used to match the Email address
  32. * @var Array
  33. */
  34. static $MODULES = array ( 'Contacts', 'Accounts', 'Leads');
  35. /**
  36. * Process the request to perform relationship operations
  37. * @global Users Instance $current_user
  38. * @global PearDataBase Instance $adb
  39. * @global String $currentModule
  40. * @param MailManager_Request $request
  41. * @return boolean
  42. */
  43. function process(MailManager_Request $request) {
  44. global $current_user, $adb;
  45. $response = new MailManager_Response(true);
  46. $viewer = $this->getViewer();
  47. if ('find' == $request->getOperationArg()) {
  48. $this->skipConnection = true; // No need to connect to mailbox here, improves performance
  49. // Check if the message is already linked.
  50. $linkedto = MailManager_RelationControllerAction::associatedLink($request->get('_msguid'));
  51. // If the message was not linked, lookup for matching records, using FROM address
  52. if (empty($linkedto)) {
  53. $results = array();
  54. $modules = array();
  55. $allowedModules = $this->getCurrentUserMailManagerAllowedModules();
  56. foreach (self::$MODULES as $MODULE) {
  57. if(!in_array($MODULE, $allowedModules)) continue;
  58. $from = $request->get('_mfrom');
  59. if(empty($from)) continue;
  60. $results[$MODULE] = $this->lookupModuleRecordsWithEmail($MODULE, $from);
  61. $describe = $this->ws_describe($MODULE);
  62. $modules[$MODULE] = array('label' => $describe['label'], 'name' => textlength_check($describe['name']), 'id' => $describe['idPrefix'] );
  63. // If look is found in a module, skip rest. - for performance
  64. //if (!empty($results[$MODULE])) break;
  65. }
  66. $viewer->assign('LOOKUPS', $results);
  67. $viewer->assign('MODULES', $modules);
  68. } else {
  69. $viewer->assign('LINKEDTO', $linkedto);
  70. }
  71. $viewer->assign('LinkToAvailableActions', $this->linkToAvailableActions());
  72. $viewer->assign('AllowedModules', $allowedModules);
  73. $viewer->assign('MSGNO', $request->get('_msgno'));
  74. $viewer->assign('FOLDER', $request->get('_folder'));
  75. $response->setResult( array( 'ui' => $viewer->fetch( $this->getModuleTpl('Relationship.tpl') ) ) );
  76. } else if ('link' == $request->getOperationArg()) {
  77. $linkto = $request->get('_mlinkto');
  78. $foldername = $request->get('_folder');
  79. $connector = $this->getConnector($foldername);
  80. // This is to handle larger uploads
  81. $memory_limit = ConfigPrefs::get('MEMORY_LIMIT');
  82. ini_set('memory_limit', $memory_limit);
  83. $mail = $connector->openMail($request->get('_msgno'));
  84. $mail->attachments(); // Initialize attachments
  85. $linkedto = MailManager_RelationControllerAction::associate($mail, $linkto);
  86. $viewer->assign('LinkToAvailableActions', $this->linkToAvailableActions());
  87. $viewer->assign('AllowedModules', $this->getCurrentUserMailManagerAllowedModules());
  88. $viewer->assign('LINKEDTO', $linkedto);
  89. $viewer->assign('MSGNO', $request->get('_msgno'));
  90. $viewer->assign('FOLDER', $foldername);
  91. $response->setResult( array( 'ui' => $viewer->fetch( $this->getModuleTpl('Relationship.tpl') ) ) );
  92. } else if ('create_wizard' == $request->getOperationArg()) {
  93. global $currentModule;
  94. $moduleName = $request->get('_mlinktotype');
  95. $parent = $request->get('_mlinkto');
  96. $foldername = $request->get('_folder');
  97. $connector = $this->getConnector($foldername);
  98. $mail = $connector->openMail($request->get('_msgno'));
  99. $qcreate_array = QuickCreate($moduleName);
  100. $validationData = $qcreate_array['data'];
  101. $data = split_validationdataArray($validationData);
  102. $qcreate_array['form'] = $this->processFormData($qcreate_array['form'], $mail);
  103. $viewer->assign("QUICKCREATE", $qcreate_array['form']);
  104. if($moduleName == 'Calendar')
  105. $viewer->assign("QCMODULE", getTranslatedString('Todo', 'Calendar'));
  106. elseif($moduleName == "HelpDesk")
  107. $viewer->assign("QCMODULE", getTranslatedString('Ticket', 'HelpDesk'));
  108. else
  109. $viewer->assign("QCMODULE",getTranslatedString("SINGLE_".$moduleName, $moduleName));
  110. $viewer->assign("PARENT", $parent);
  111. $viewer->assign("MODULE", $moduleName);
  112. $viewer->assign('MSGNO', $request->get('_msgno'));
  113. $viewer->assign('FOLDER', $foldername);
  114. $viewer->assign("VALIDATION_DATA_FIELDNAME",$data['fieldname']);
  115. $viewer->assign("VALIDATION_DATA_FIELDDATATYPE",$data['datatype']);
  116. $viewer->assign("VALIDATION_DATA_FIELDLABEL",$data['fieldlabel']);
  117. $viewer->display( $this->getModuleTpl('Relationship.CreateWizard.tpl') );
  118. $response = false;
  119. } else if ('create' == $request->getOperationArg()) {
  120. $linkModule = $request->get('_mlinktotype');
  121. $parent = $request->get('_mlinkto');
  122. $focus = CRMEntity::getInstance($linkModule);
  123. // This is added as ModComments module has a bug that will not initialize column_fields
  124. // Basically $currentModule is set to MailManager, so the fields are not set properly.
  125. if(empty($focus->column_fields)) {
  126. $focus->column_fields = getColumnFields($linkModule);
  127. }
  128. setObjectValuesFromRequest($focus);
  129. if($request->get('assigntype') == 'U') {
  130. $focus->column_fields['assigned_user_id'] = $request->get('assigned_user_id');
  131. } elseif($request->get('assigntype') == 'T') {
  132. $focus->column_fields['assigned_user_id'] = $request->get('assigned_group_id');
  133. }
  134. $foldername = $request->get('_folder');
  135. if(!empty($foldername)) {
  136. // This is to handle larger uploads
  137. $memory_limit = ConfigPrefs::get('MEMORY_LIMIT');
  138. ini_set('memory_limit', $memory_limit);
  139. $connector = $this->getConnector($foldername);
  140. $mail = $connector->openMail($request->get('_msgno'));
  141. $attachments = $mail->attachments(); // Initialize attachments
  142. }
  143. $linkedto = MailManager_RelationControllerAction::getSalesEntityInfo($parent);
  144. switch ($linkModule) {
  145. case 'Calendar' : if (empty($focus->column_fields['activitytype'])) {
  146. $focus->column_fields['activitytype'] = 'Task';
  147. }
  148. if (empty($focus->column_fields['due_date'])) {
  149. if(!empty($focus->column_fields['date_start'])) {
  150. $dateStart = getValidDBInsertDateValue($focus->column_fields['date_start']);
  151. $focus->column_fields['due_date'] = date("Y-m-d", strtotime(date("Y-m-d", strtotime($dateStart)) . " +1 day"));
  152. } else {
  153. $focus->column_fields['due_date'] = date('Y-m-d', strtotime("+1 day"));
  154. }
  155. }
  156. if(!empty($parent)) {
  157. if($linkedto['module'] == 'Contacts') {
  158. $focus->column_fields['contact_id'] = $parent;
  159. } else {
  160. $focus->column_fields['parent_id'] = $parent;
  161. }
  162. }
  163. break;
  164. case 'HelpDesk' : $from = $mail->from();
  165. $focus->column_fields['parent_id'] = $this->setParentForHelpDesk($parent, $from);
  166. break;
  167. case 'ModComments': $focus->column_fields['assigned_user_id'] = $current_user->id;
  168. $focus->column_fields['creator'] = $current_user->id;
  169. $focus->column_fields['related_to'] = $parent;
  170. break;
  171. }
  172. try {
  173. $focus->save($linkModule);
  174. // This condition is added so that emails are not created for Tickets and Todo without Parent,
  175. // as there is no way to relate them
  176. if(empty($parent) && $linkModule != 'HelpDesk' && $linkModule != 'Calendar') {
  177. $linkedto = MailManager_RelationControllerAction::associate($mail, $focus->id);
  178. }
  179. // add attachments to the tickets as Documents
  180. if($linkModule == 'HelpDesk' && !empty($attachments)) {
  181. $relationController = new MailManager_RelationControllerAction();
  182. $relationController->__SaveAttachements($mail, $linkModule, $focus);
  183. }
  184. $viewer->assign('MSGNO', $request->get('_msgno'));
  185. $viewer->assign('LINKEDTO', $linkedto);
  186. $viewer->assign('AllowedModules', $this->getCurrentUserMailManagerAllowedModules());
  187. $viewer->assign('LinkToAvailableActions', $this->linkToAvailableActions());
  188. $viewer->assign('FOLDER', $foldername);
  189. $response->setResult( array( 'ui' => $viewer->fetch( $this->getModuleTpl('Relationship.tpl') ) ) );
  190. } catch(Exception $e) {
  191. $response->setResult( array( 'ui' => '', 'error' => $e ));
  192. }
  193. } else if ('savedraft' == $request->getOperationArg()) {
  194. $connector = $this->getConnector('__vt_drafts');
  195. $draftResponse = $connector->saveDraft($request);
  196. $response->setResult($draftResponse);
  197. } else if ('saveattachment' == $request->getOperationArg()) {
  198. $connector = $this->getConnector('__vt_drafts');
  199. $uploadResponse = $connector->saveAttachment($request);
  200. $response->setResult($uploadResponse);
  201. } else if ('commentwidget' == $request->getOperationArg()) {
  202. $viewer->assign('LINKMODULE', $request->get('_mlinktotype'));
  203. $viewer->assign('PARENT', $request->get('_mlinkto'));
  204. $viewer->assign('MSGNO', $request->get('_msgno'));
  205. $viewer->assign('FOLDER', $request->get('_folder'));
  206. $viewer->display( $this->getModuleTpl('MailManager.CommentWidget.tpl') );
  207. $response = false;
  208. }
  209. return $response;
  210. }
  211. /**
  212. * Returns the Parent for Tickets module
  213. * @global Users Instance $current_user
  214. * @param Integer $parent - crmid of Parent
  215. * @param Email Address $from - Email Address of the received mail
  216. * @return Integer - Parent(crmid)
  217. */
  218. public function setParentForHelpDesk($parent, $from) {
  219. global $current_user;
  220. if(empty($parent)) {
  221. if(!empty($from)) {
  222. $parentInfo = MailManager::lookupMailInVtiger($from[0], $current_user);
  223. if(!empty($parentInfo[0]['record'])) {
  224. $parentId = vtws_getIdComponents($parentInfo[0]['record']);
  225. return $parentId[1];
  226. }
  227. }
  228. } else {
  229. return $parent;
  230. }
  231. }
  232. /**
  233. * Function used to set the record fields with the information from mail.
  234. * @param Array $qcreate_array
  235. * @param MailManager_Model_Message $mail
  236. * @return Array
  237. */
  238. function processFormData($qcreate_array, $mail) {
  239. $subject = $mail->subject();
  240. $from = $mail->from();
  241. if(!empty($from)) $mail_fromAddress = implode(',', $from);
  242. if(!empty($mail_fromAddress)) $name = explode('@', $mail_fromAddress);
  243. if(!empty($name[1])) $companyName = explode('.', $name[1]);
  244. $defaultFieldValueMap = array( 'lastname' => $name[0],
  245. 'email' => $mail_fromAddress,
  246. 'email1' => $mail_fromAddress,
  247. 'accountname' => $companyName[0],
  248. 'company' => $companyName[0],
  249. 'ticket_title' => $subject,
  250. 'subject' => $subject,
  251. );
  252. $defaultFieldValueMapKeys = array_keys($defaultFieldValueMap);
  253. foreach($qcreate_array as $qc_array) {
  254. $new_qc_array = array();
  255. foreach($qc_array as $q_array) {
  256. if(in_array($q_array[2][0], $defaultFieldValueMapKeys)) {
  257. if($q_array[2][0] == "lastname") {
  258. $q_array[3][1] = $defaultFieldValueMap[$q_array[2][0]];
  259. } else {
  260. $q_array[3][0] = $defaultFieldValueMap[$q_array[2][0]];
  261. }
  262. }
  263. $new_qc_array[] = $q_array;
  264. }
  265. $new_qcreate_array[] = $new_qc_array;
  266. }
  267. return $new_qcreate_array;
  268. }
  269. /**
  270. * Returns the available List of accessible modules for Mail Manager
  271. * @return Array
  272. */
  273. public function getCurrentUserMailManagerAllowedModules() {
  274. $moduleListForCreateRecordFromMail = array('Contacts', 'Accounts', 'Leads', 'HelpDesk', 'Calendar');
  275. foreach($moduleListForCreateRecordFromMail as $module) {
  276. if(MailManager::checkModuleWriteAccessForCurrentUser($module)) {
  277. $mailManagerAllowedModules[] = $module;
  278. }
  279. }
  280. return $mailManagerAllowedModules;
  281. }
  282. /**
  283. * Returns the list of accessible modules on which Actions(Relationship) can be taken.
  284. * @return string
  285. */
  286. public function linkToAvailableActions() {
  287. $moduleListForLinkTo = array('Calendar','HelpDesk','ModComments','Emails');
  288. foreach($moduleListForLinkTo as $module) {
  289. if(MailManager::checkModuleWriteAccessForCurrentUser($module)) {
  290. $mailManagerAllowedModules[] = $module;
  291. }
  292. }
  293. return $mailManagerAllowedModules;
  294. }
  295. /**
  296. * Helper function to scan for relations
  297. */
  298. protected $wsDescribeCache = array();
  299. function ws_describe($module) {
  300. global $current_user;
  301. if (!isset($this->wsDescribeCache[$module])) {
  302. $this->wsDescribeCache[$module] = vtws_describe( $module, $current_user );
  303. }
  304. return $this->wsDescribeCache[$module];
  305. }
  306. /**
  307. * Funtion used to build Web services query
  308. * @param String $module - Name of the module
  309. * @param String $text - Search String
  310. * @param String $type - Tyoe of fields Phone, Email etc
  311. * @return String
  312. */
  313. function buildSearchQuery($module, $text, $type) {
  314. $describe = $this->ws_describe($module);
  315. $whereClause = '';
  316. foreach($describe['fields'] as $field) {
  317. if (strcasecmp($type, $field['type']['name']) === 0) {
  318. $whereClause .= sprintf( " %s LIKE '%%%s%%' OR", $field['name'], $text );
  319. }
  320. }
  321. return sprintf( "SELECT %s FROM %s WHERE %s;", $describe['labelFields'], $module, rtrim($whereClause, 'OR') );
  322. }
  323. /**
  324. * Returns the List of Matching records with the Email Address
  325. * @global Users Instance $current_user
  326. * @param String $module
  327. * @param Email Address $email
  328. * @return Array
  329. */
  330. function lookupModuleRecordsWithEmail($module, $email) {
  331. global $current_user;
  332. $query = $this->buildSearchQuery($module, $email, 'EMAIL');
  333. $qresults = vtws_query( $query, $current_user );
  334. $describe = $this->ws_describe($module);
  335. $labelFields = explode(',', $describe['labelFields']);
  336. $results = array();
  337. foreach($qresults as $qresult) {
  338. $labelValues = array();
  339. foreach($labelFields as $fieldname) {
  340. if(isset($qresult[$fieldname])) $labelValues[] = $qresult[$fieldname];
  341. }
  342. $ids = vtws_getIdComponents($qresult['id']);
  343. $results[] = array( 'wsid' => $qresult['id'], 'id' => $ids[1], 'label' => implode(' ', $labelValues));
  344. }
  345. return $results;
  346. }
  347. }
  348. ?>