PageRenderTime 46ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/modules/Reports/ScheduledReports.php

https://bitbucket.org/thomashii/vtigercrm-5.4-for-postgresql
PHP | 379 lines | 315 code | 56 blank | 8 comment | 57 complexity | 6299a1666a9a70833cea798c05fa21e4 MD5 | raw file
Possible License(s): LGPL-2.1, GPL-2.0
  1. <?php
  2. /*+***********************************************************************************
  3. * The contents of this file are subject to the vtiger CRM Public License Version 1.0
  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. require_once 'modules/Reports/Reports.php';
  11. require_once 'modules/Reports/ReportRun.php';
  12. require_once 'include/Zend/Json.php';
  13. class VTScheduledReport extends Reports {
  14. var $db;
  15. var $user;
  16. var $isScheduled = false;
  17. var $scheduledInterval = null;
  18. var $scheduledFormat = null;
  19. var $scheduledRecipients = null;
  20. static $SCHEDULED_HOURLY = 1;
  21. static $SCHEDULED_DAILY = 2;
  22. static $SCHEDULED_WEEKLY = 3;
  23. static $SCHEDULED_BIWEEKLY = 4;
  24. static $SCHEDULED_MONTHLY = 5;
  25. static $SCHEDULED_ANNUALLY = 6;
  26. public function __construct($adb, $user, $reportid="") {
  27. $this->db = $adb;
  28. $this->user = $user;
  29. $this->id = $reportid;
  30. parent::__construct($reportid);
  31. }
  32. public function getReportScheduleInfo() {
  33. global $adb;
  34. if(!empty($this->id)) {
  35. $cachedInfo = VTCacheUtils::lookupReport_ScheduledInfo($this->user->id, $this->id);
  36. if($cachedInfo == false) {
  37. $result = $adb->pquery('SELECT * FROM vtiger_scheduled_reports WHERE reportid=?', array($this->id));
  38. if($adb->num_rows($result) > 0) {
  39. $reportScheduleInfo = $adb->raw_query_result_rowdata($result, 0);
  40. $scheduledInterval = (!empty($reportScheduleInfo['schedule']))?Zend_Json::decode($reportScheduleInfo['schedule']):array();
  41. $scheduledRecipients = (!empty($reportScheduleInfo['recipients']))?Zend_Json::decode($reportScheduleInfo['recipients']):array();
  42. VTCacheUtils::updateReport_ScheduledInfo($this->user->id, $this->id, true, $reportScheduleInfo['format'],
  43. $scheduledInterval, $scheduledRecipients, $reportScheduleInfo['next_trigger_time']);
  44. $cachedInfo = VTCacheUtils::lookupReport_ScheduledInfo($this->user->id, $this->id);
  45. }
  46. }
  47. if($cachedInfo) {
  48. $this->isScheduled = $cachedInfo['isScheduled'];
  49. $this->scheduledFormat = $cachedInfo['scheduledFormat'];
  50. $this->scheduledInterval = $cachedInfo['scheduledInterval'];
  51. $this->scheduledRecipients = $cachedInfo['scheduledRecipients'];
  52. $this->scheduledTime = $cachedInfo['scheduledTime'];
  53. return true;
  54. }
  55. }
  56. return false;
  57. }
  58. public function getRecipientEmails() {
  59. $recipientsInfo = $this->scheduledRecipients;
  60. $recipientsList = array();
  61. if(!empty($recipientsInfo)) {
  62. if(!empty($recipientsInfo['users'])) {
  63. $recipientsList = array_merge($recipientsList, $recipientsInfo['users']);
  64. }
  65. if(!empty($recipientsInfo['roles'])) {
  66. foreach($recipientsInfo['roles'] as $roleId) {
  67. $roleUsers = getRoleUsers($roleId);
  68. foreach($roleUsers as $userId => $userName) {
  69. array_push($recipientsList, $userId);
  70. }
  71. }
  72. }
  73. if(!empty($recipientsInfo['rs'])) {
  74. foreach($recipientsInfo['rs'] as $roleId) {
  75. $users = getRoleAndSubordinateUsers($roleId);
  76. foreach($users as $userId => $userName) {
  77. array_push($recipientsList, $userId);
  78. }
  79. }
  80. }
  81. if(!empty($recipientsInfo['groups'])) {
  82. require_once 'include/utils/GetGroupUsers.php';
  83. foreach($recipientsInfo['groups'] as $groupId) {
  84. $userGroups = new GetGroupUsers();
  85. $userGroups->getAllUsersInGroup($groupId);
  86. $recipientsList = array_merge($recipientsList, $userGroups->group_users);
  87. }
  88. }
  89. }
  90. $recipientsEmails = array();
  91. if(!empty($recipientsList) && count($recipientsList) > 0) {
  92. foreach($recipientsList as $userId) {
  93. $userName = getUserFullName($userId);
  94. $userEmail = getUserEmail($userId);
  95. if(!in_array($userEmail, $recipientsEmails)) {
  96. $recipientsEmails[$userName] = $userEmail;
  97. }
  98. }
  99. }
  100. return $recipientsEmails;
  101. }
  102. public function sendEmail() {
  103. global $currentModule;
  104. require_once 'vtlib/Vtiger/Mailer.php';
  105. $vtigerMailer = new Vtiger_Mailer();
  106. $recipientEmails = $this->getRecipientEmails();
  107. foreach($recipientEmails as $name => $email) {
  108. $vtigerMailer->AddAddress($email, $name);
  109. }
  110. $currentTime = date('Y-m-d H:i:s');
  111. $subject = $this->reportname .' - '. $currentTime .' ('. DateTimeField::getDBTimeZone() .')';
  112. $contents = getTranslatedString('LBL_AUTO_GENERATED_REPORT_EMAIL', $currentModule) .'<br/><br/>';
  113. $contents .= '<b>'.getTranslatedString('LBL_REPORT_NAME', $currentModule) .' :</b> '. $this->reportname .'<br/>';
  114. $contents .= '<b>'.getTranslatedString('LBL_DESCRIPTION', $currentModule) .' :</b><br/>'. $this->reportdescription .'<br/><br/>';
  115. $vtigerMailer->Subject = $subject;
  116. $vtigerMailer->Body = $contents;
  117. $vtigerMailer->ContentType = "text/html";
  118. $baseFileName = preg_replace('/[^a-zA-Z0-9_-\s]/', '', $this->reportname).'_'. preg_replace('/[^a-zA-Z0-9_-\s]/', '', $currentTime);
  119. $oReportRun = new ReportRun($this->id);
  120. $reportFormat = $this->scheduledFormat;
  121. $attachments = array();
  122. if($reportFormat == 'pdf' || $reportFormat == 'both') {
  123. $fileName = $baseFileName.'.pdf';
  124. $filePath = 'storage/'.$fileName;
  125. $attachments[$fileName] = $filePath;
  126. $pdf = $oReportRun->getReportPDF();
  127. $pdf->Output($filePath,'F');
  128. }
  129. if ($reportFormat == 'excel' || $reportFormat == 'both') {
  130. $fileName = $baseFileName.'.xls';
  131. $filePath = 'storage/'.$fileName;
  132. $attachments[$fileName] = $filePath;
  133. $oReportRun->writeReportToExcelFile($filePath);
  134. }
  135. foreach($attachments as $attachmentName => $path) {
  136. $vtigerMailer->AddAttachment($path, $attachmentName);
  137. }
  138. $vtigerMailer->Send(true);
  139. foreach($attachments as $attachmentName => $path) {
  140. unlink($path);
  141. }
  142. }
  143. public function getNextTriggerTime() {
  144. $scheduleInfo = $this->scheduledInterval;
  145. $scheduleType = $scheduleInfo['scheduletype'];
  146. $scheduledMonth = $scheduleInfo['month'];
  147. $scheduledDayOfMonth= $scheduleInfo['date'];
  148. $scheduledDayOfWeek = $scheduleInfo['day'];
  149. $scheduledTime = $scheduleInfo['time'];
  150. if(empty($scheduledTime)) {
  151. $scheduledTime = '10:00';
  152. } elseif(stripos(':', $scheduledTime) === false) {
  153. $scheduledTime = $scheduledTime .':00';
  154. }
  155. if($scheduleType == VTScheduledReport::$SCHEDULED_HOURLY) {
  156. return date("Y-m-d H:i:s",strtotime("+1 hour"));
  157. }
  158. if($scheduleType == VTScheduledReport::$SCHEDULED_DAILY) {
  159. return date("Y-m-d H:i:s",strtotime("+ 1 day ".$scheduledTime));
  160. }
  161. if($scheduleType == VTScheduledReport::$SCHEDULED_WEEKLY) {
  162. $weekDays = array('0'=>'Sunday','1'=>'Monday','2'=>'Tuesday','3'=>'Wednesday','4'=>'Thursday','5'=>'Friday','6'=>'Saturday');
  163. if(date('w',time()) == $scheduledDayOfWeek) {
  164. return date("Y-m-d H:i:s",strtotime('+1 week '.$scheduledTime));
  165. } else {
  166. return date("Y-m-d H:i:s",strtotime($weekDays[$scheduledDayOfWeek].' '.$scheduledTime));
  167. }
  168. }
  169. if($scheduleType == VTScheduledReport::$SCHEDULED_BIWEEKLY) {
  170. $weekDays = array('0'=>'Sunday','1'=>'Monday','2'=>'Tuesday','3'=>'Wednesday','4'=>'Thursday','5'=>'Friday','6'=>'Saturday');
  171. if(date('w',time()) == $scheduledDayOfWeek) {
  172. return date("Y-m-d H:i:s",strtotime('+2 weeks '.$scheduledTime));
  173. } else {
  174. return date("Y-m-d H:i:s",strtotime($weekDays[$scheduledDayOfWeek].' '.$scheduledTime));
  175. }
  176. }
  177. if($scheduleType == VTScheduledReport::$SCHEDULED_MONTHLY) {
  178. $currentTime = time();
  179. $currentDayOfMonth = date('j',$currentTime);
  180. if($scheduledDayOfMonth == $currentDayOfMonth) {
  181. return date("Y-m-d H:i:s",strtotime('+1 month '.$scheduledTime));
  182. } else {
  183. $monthInFullText = date('F',$currentTime);
  184. $yearFullNumberic = date('Y',$currentTime);
  185. if($scheduledDayOfMonth < $currentDayOfMonth) {
  186. $nextMonth = date("Y-m-d H:i:s",strtotime('next month'));
  187. $monthInFullText = date('F',strtotime($nextMonth));
  188. }
  189. return date("Y-m-d H:i:s",strtotime($scheduledDayOfMonth.' '.$monthInFullText.' '.$yearFullNumberic.' '.$scheduledTime));
  190. }
  191. }
  192. if($scheduleType == VTScheduledReport::$SCHEDULED_ANNUALLY) {
  193. $months = array(0=>'January',1=>'February',2=>'March',3=>'April',4=>'May',5=>'June',6=>'July',
  194. 7=>'August',8=>'September',9=>'October',10=>'November',11=>'December');
  195. $currentTime = time();
  196. $currentMonth = date('n',$currentTime);
  197. if(($scheduledMonth+1) == $currentMonth) {
  198. return date("Y-m-d H:i:s",strtotime('+1 year '.$scheduledTime));
  199. } else {
  200. $monthInFullText = $months[$scheduledMonth];
  201. $yearFullNumberic = date('Y',$currentTime);
  202. if(($scheduledMonth+1) < $currentMonth) {
  203. $nextMonth = date("Y-m-d H:i:s",strtotime('next year'));
  204. $yearFullNumberic = date('Y',strtotime($nextMonth));
  205. }
  206. return date("Y-m-d H:i:s",strtotime($scheduledDayOfMonth.' '.$monthInFullText.' '.$yearFullNumberic.' '.$scheduledTime));
  207. }
  208. }
  209. }
  210. public function updateNextTriggerTime() {
  211. $adb = $this->db;
  212. $currentTime = date('Y-m-d H:i:s');
  213. $scheduledInterval = $this->scheduledInterval;
  214. $nextTriggerTime = $this->getNextTriggerTime(); // Compute based on the frequency set
  215. $adb->pquery('UPDATE vtiger_scheduled_reports SET next_trigger_time=? WHERE reportid=?', array($nextTriggerTime, $this->id));
  216. }
  217. public static function generateRecipientOption($type, $value, $name='') {
  218. switch($type) {
  219. case "users" : if(empty($name)) $name = getUserFullName($value);
  220. $optionName = 'User::'.addslashes(decode_html($name));
  221. $optionValue = 'users::'.$value;
  222. break;
  223. case "groups" : if(empty($name)) {
  224. $groupInfo = getGroupName($value);
  225. $name = $groupInfo[0];
  226. }
  227. $optionName = 'Group::'.addslashes(decode_html($name));
  228. $optionValue = 'groups::'.$value;
  229. break;
  230. case "roles" : if(empty($name)) $name = getRoleName ($value);
  231. $optionName = 'Roles::'.addslashes(decode_html($name));
  232. $optionValue = 'roles::'.$value;
  233. break;
  234. case "rs" : if(empty($name)) $name = getRoleName ($value);
  235. $optionName = 'RoleAndSubordinates::'.addslashes(decode_html($name));
  236. $optionValue = 'rs::'.$value;
  237. break;
  238. }
  239. return '<option value="'.$optionValue.'">'.$optionName.'</option>';
  240. }
  241. public function getSelectedRecipientsHTML() {
  242. $selectedRecipientsHTML = '';
  243. if(!empty($this->scheduledRecipients)) {
  244. foreach($this->scheduledRecipients as $recipientType => $recipients) {
  245. foreach($recipients as $recipientId) {
  246. $selectedRecipientsHTML .= VTScheduledReport::generateRecipientOption($recipientType, $recipientId);
  247. }
  248. }
  249. }
  250. return $selectedRecipientsHTML;
  251. }
  252. public static function getAvailableUsersHTML() {
  253. $userDetails = getAllUserName();
  254. $usersHTML = '<select id="availableRecipients" name="availableRecipients" multiple size="10" class="small crmFormList">';
  255. foreach($userDetails as $userId=>$userName) {
  256. $usersHTML .= VTScheduledReport::generateRecipientOption('users', $userId, $userName);
  257. }
  258. $usersHTML .= '</select>';
  259. return $usersHTML;
  260. }
  261. public static function getAvailableGroupsHTML() {
  262. $grpDetails = getAllGroupName();
  263. $groupsHTML = '<select id="availableRecipients" name="availableRecipients" multiple size="10" class="small crmFormList">';
  264. foreach($grpDetails as $groupId=>$groupName) {
  265. $groupsHTML .= VTScheduledReport::generateRecipientOption('groups', $groupId, $groupName);
  266. }
  267. $groupsHTML .= '</select>';
  268. return $groupsHTML;
  269. }
  270. public static function getAvailableRolesHTML() {
  271. $roleDetails = getAllRoleDetails();
  272. $rolesHTML = '<select id="availableRecipients" name="availableRecipients" multiple size="10" class="small crmFormList">';
  273. foreach($roleDetails as $roleId=>$roleInfo) {
  274. $rolesHTML .= VTScheduledReport::generateRecipientOption('roles', $roleId, $roleInfo[0]);
  275. }
  276. $rolesHTML .= '</select>';
  277. return $rolesHTML;
  278. }
  279. public static function getAvailableRolesAndSubordinatesHTML() {
  280. $roleDetails = getAllRoleDetails();
  281. $rolesAndSubHTML = '<select id="availableRecipients" name="availableRecipients" multiple size="10" class="small crmFormList">';
  282. foreach($roleDetails as $roleId=>$roleInfo) {
  283. $rolesAndSubHTML .= VTScheduledReport::generateRecipientOption('rs', $roleId, $roleInfo[0]);
  284. }
  285. $rolesAndSubHTML .= '</select>';
  286. return $rolesAndSubHTML;
  287. }
  288. public static function getScheduledReports($adb, $user) {
  289. $currentTime = date('Y-m-d H:i:s');
  290. $result = $adb->pquery("SELECT * FROM vtiger_scheduled_reports
  291. WHERE next_trigger_time = '' || next_trigger_time <= ?", array($currentTime));
  292. $scheduledReports = array();
  293. $noOfScheduledReports = $adb->num_rows($result);
  294. for($i=0; $i<$noOfScheduledReports; ++$i) {
  295. $reportScheduleInfo = $adb->raw_query_result_rowdata($result, $i);
  296. $scheduledInterval = (!empty($reportScheduleInfo['schedule']))?Zend_Json::decode($reportScheduleInfo['schedule']):array();
  297. $scheduledRecipients = (!empty($reportScheduleInfo['recipients']))?Zend_Json::decode($reportScheduleInfo['recipients']):array();
  298. $vtScheduledReport = new VTScheduledReport($adb, $user, $reportScheduleInfo['reportid']);
  299. $vtScheduledReport->isScheduled = true;
  300. $vtScheduledReport->scheduledFormat = $reportScheduleInfo['format'];
  301. $vtScheduledReport->scheduledInterval = $scheduledInterval;
  302. $vtScheduledReport->scheduledRecipients = $scheduledRecipients;
  303. $vtScheduledReport->scheduledTime = $reportScheduleInfo['next_trigger_time'];
  304. $scheduledReports[] = $vtScheduledReport;
  305. }
  306. return $scheduledReports;
  307. }
  308. public static function runScheduledReports($adb) {
  309. require_once 'modules/com_vtiger_workflow/VTWorkflowUtils.php';
  310. $util = new VTWorkflowUtils();
  311. $adminUser = $util->adminUser();
  312. global $currentModule, $current_language;
  313. if(empty($currentModule)) $currentModule = 'Reports';
  314. if(empty($current_language)) $current_language = 'en_us';
  315. $scheduledReports = self::getScheduledReports($adb, $adminUser);
  316. foreach($scheduledReports as $scheduledReport) {
  317. $scheduledReport->sendEmail();
  318. $scheduledReport->updateNextTriggerTime();
  319. }
  320. $util->revertUser();
  321. }
  322. }
  323. ?>