[ Index ] |
PHP Cross Reference of vtigercrm-6.1.0 |
[Summary view] [Print] [Text view]
1 <?php 2 3 /* +*********************************************************************************** 4 * The contents of this file are subject to the vtiger CRM Public License Version 1.0 5 * ("License"); You may not use this file except in compliance with the License 6 * The Original Code is: vtiger CRM Open Source 7 * The Initial Developer of the Original Code is vtiger. 8 * Portions created by vtiger are Copyright (C) vtiger. 9 * All Rights Reserved. 10 * *********************************************************************************** */ 11 12 require_once ('modules/com_vtiger_workflow/WorkflowScheduler.inc'); 13 require_once ('modules/com_vtiger_workflow/VTWorkflowUtils.php'); 14 require_once 'modules/Users/Users.php'; 15 16 class WorkFlowScheduler { 17 18 private $user; 19 private $db; 20 21 public function __construct($adb) { 22 $util = new VTWorkflowUtils(); 23 $adminUser = $util->adminUser(); 24 $this->user = $adminUser; 25 $this->db = $adb; 26 } 27 28 public function getWorkflowQuery($workflow) { 29 $conditions = Zend_Json :: decode(decode_html($workflow->test)); 30 31 $moduleName = $workflow->moduleName; 32 $queryGenerator = new QueryGenerator($moduleName, $this->user); 33 $queryGenerator->setFields(array('id')); 34 $this->addWorkflowConditionsToQueryGenerator($queryGenerator, $conditions); 35 36 if($moduleName == 'Calendar' || $moduleName == 'Events') { 37 if($conditions){ 38 $queryGenerator->addConditionGlue('AND'); 39 } 40 // We should only get the records related to proper activity type 41 if($moduleName == 'Calendar'){ 42 $queryGenerator->addCondition('activitytype','Emails','n'); 43 $queryGenerator->addCondition('activitytype','Task','e','AND'); 44 }else if($moduleName == "Events"){ 45 $queryGenerator->addCondition('activitytype','Emails','n'); 46 $queryGenerator->addCondition('activitytype','Task','n','AND'); 47 } 48 } 49 50 $query = $queryGenerator->getQuery(); 51 return $query; 52 } 53 54 public function getEligibleWorkflowRecords($workflow) { 55 $adb = $this->db; 56 $query = $this->getWorkflowQuery($workflow); 57 $result = $adb->query($query); 58 $noOfRecords = $adb->num_rows($result); 59 $recordsList = array(); 60 for ($i = 0; $i < $noOfRecords; ++$i) { 61 $recordsList[] = $adb->query_result($result, $i, 0); 62 } 63 $result = null; 64 return $recordsList; 65 } 66 67 public function queueScheduledWorkflowTasks() { 68 global $default_timezone; 69 $adb = $this->db; 70 71 $vtWorflowManager = new VTWorkflowManager($adb); 72 $taskQueue = new VTTaskQueue($adb); 73 $entityCache = new VTEntityCache($this->user); 74 75 // set the time zone to the admin's time zone, this is needed so that the scheduled workflow will be triggered 76 // at admin's time zone rather than the systems time zone. This is specially needed for Hourly and Daily scheduled workflows 77 $admin = Users::getActiveAdminUser(); 78 $adminTimeZone = $admin->time_zone; 79 @date_default_timezone_set($adminTimeZone); 80 $currentTimestamp = date("Y-m-d H:i:s"); 81 @date_default_timezone_set($default_timezone); 82 83 $scheduledWorkflows = $vtWorflowManager->getScheduledWorkflows($currentTimestamp); 84 $noOfScheduledWorkflows = count($scheduledWorkflows); 85 for ($i = 0; $i < $noOfScheduledWorkflows; ++$i) { 86 $workflow = $scheduledWorkflows[$i]; 87 $tm = new VTTaskManager($adb); 88 $tasks = $tm->getTasksForWorkflow($workflow->id); 89 if ($tasks) { 90 $records = $this->getEligibleWorkflowRecords($workflow); 91 $noOfRecords = count($records); 92 for ($j = 0; $j < $noOfRecords; ++$j) { 93 $recordId = $records[$j]; 94 // We need to pass proper module name to get the webservice 95 if($workflow->moduleName == 'Calendar') { 96 $moduleName = vtws_getCalendarEntityType($recordId); 97 } else { 98 $moduleName = $workflow->moduleName; 99 } 100 $wsEntityId = vtws_getWebserviceEntityId($moduleName, $recordId); 101 $entityData = $entityCache->forId($wsEntityId); 102 $data = $entityData->getData(); 103 foreach ($tasks as $task) { 104 if ($task->active) { 105 $trigger = $task->trigger; 106 if ($trigger != null) { 107 $delay = strtotime($data[$trigger['field']]) + $trigger['days'] * 86400; 108 } else { 109 $delay = 0; 110 } 111 if ($task->executeImmediately == true) { 112 $task->doTask($entityData); 113 } else { 114 $taskQueue->queueTask($task->id, $entityData->getId(), $delay); 115 } 116 } 117 } 118 } 119 } 120 $vtWorflowManager->updateNexTriggerTime($workflow); 121 } 122 $scheduledWorkflows = null; 123 } 124 125 function addWorkflowConditionsToQueryGenerator($queryGenerator, $conditions) { 126 $conditionMapping = array( 127 "equal to" => 'e', 128 "less than" => 'l', 129 "greater than" => 'g', 130 "does not equal" => 'n', 131 "less than or equal to" => 'm', 132 "greater than or equal to" => 'h', 133 "is" => 'e', 134 "contains" => 'c', 135 "does not contain" => 'k', 136 "starts with" => 's', 137 "ends with" => 'ew', 138 "is not" => 'n', 139 "is not empty" => 'n', 140 'before' => 'l', 141 'after' => 'g', 142 'between' => 'bw', 143 'less than days ago' => 'bw', 144 'more than days ago' => 'l', 145 'in less than' => 'bw', 146 'in more than' => 'g', 147 'days ago' => 'e', 148 'days later' => 'e', 149 'less than hours before' => 'bw', 150 'less than hours later' => 'bw', 151 'more than hours before' => 'l', 152 'more than hours later' => 'g', 153 'is today' => 'e', 154 ); 155 $noOfConditions = count($conditions); 156 //Algorithm : 157 //1. If the query has already where condition then start a new group with and condition, else start a group 158 //2. Foreach of the condition, if its a condition in the same group just append with the existing joincondition 159 //3. If its a new group, then start the group with the group join. 160 //4. And for the first condition in the new group, dont append any joincondition. 161 162 if ($noOfConditions > 0) { 163 if ($queryGenerator->conditionInstanceCount > 0) { 164 $queryGenerator->startGroup(QueryGenerator::$AND); 165 } else { 166 $queryGenerator->startGroup(''); 167 } 168 foreach ($conditions as $index => $condition) { 169 $operation = $condition['operation']; 170 171 //Cannot handle this condition for scheduled workflows 172 if($operation == 'has changed') continue; 173 174 $value = $condition['value']; 175 if(in_array($operation, $this->_specialDateTimeOperator())) { 176 $value = $this->_parseValueForDate($condition); 177 } 178 $columnCondition = $condition['joincondition']; 179 $groupId = $condition['groupid']; 180 $groupJoin = $condition['groupjoin']; 181 $operator = $conditionMapping[$operation]; 182 $fieldname = $condition['fieldname']; 183 $valueType = $condition['valuetype']; 184 185 if($index > 0 && $groupId != $conditions[$index-1]['groupid']) { // if new group, end older group and start new 186 $queryGenerator->endGroup(); 187 if($groupJoin) { 188 $queryGenerator->startGroup($groupJoin); 189 } else { 190 $queryGenerator->startGroup(QueryGenerator::$AND); 191 } 192 } 193 194 if($index > 0 && $groupId != $conditions[$index-1]['groupid']) { //if first condition in new group, send empty condition to append 195 $columnCondition = null; 196 } else if(empty($columnCondition) && $index > 0) { 197 $columnCondition = $conditions[$index-1]['joincondition']; 198 } 199 $value = html_entity_decode($value); 200 preg_match('/(\w+) : \((\w+)\) (\w+)/', $condition['fieldname'], $matches); 201 if (count($matches) != 0) { 202 list($full, $referenceField, $referenceModule, $fieldname) = $matches; 203 } 204 if($referenceField) { 205 $queryGenerator->addReferenceModuleFieldCondition($referenceModule, $referenceField, $fieldname, $value, $operator, $columnCondition); 206 $referenceField = null; 207 } else { 208 $queryGenerator->addCondition($fieldname, $value, $operator, $columnCondition); 209 } 210 } 211 $queryGenerator->endGroup(); 212 } 213 } 214 215 /** 216 * Special Date functions 217 * @return <Array> 218 */ 219 function _specialDateTimeOperator() { 220 return array('less than days ago', 'more than days ago', 'in less than', 'in more than', 'days ago', 'days later', 221 'less than hours before', 'less than hours later', 'more than hours later', 'more than hours before', 'is today'); 222 } 223 224 /** 225 * Function parse the value based on the condition 226 * @param <Array> $condition 227 * @return <String> 228 */ 229 function _parseValueForDate($condition) { 230 $value = $condition['value']; 231 $operation = $condition['operation']; 232 233 // based on the admin users time zone, since query generator expects datetime at user timezone 234 global $default_timezone; 235 $admin = Users::getActiveAdminUser(); 236 $adminTimeZone = $admin->time_zone; 237 @date_default_timezone_set($adminTimeZone); 238 239 switch($operation) { 240 case 'less than days ago' : //between current date and (currentdate - givenValue) 241 $days = $condition['value']; 242 $value = date('Y-m-d', strtotime('-'.$days.' days')).','.date('Y-m-d', strtotime('+1 day')); 243 break; 244 245 case 'more than days ago' : // less than (current date - givenValue) 246 $days = $condition['value']-1; 247 $value = date('Y-m-d', strtotime('-'.$days.' days')); 248 break; 249 250 case 'in less than' : // between current date and future date(current date + givenValue) 251 $days = $condition['value']+1; 252 $value = date('Y-m-d', strtotime('-1 day')).','.date('Y-m-d', strtotime('+'.$days.' days')); 253 break; 254 255 case 'in more than' : // greater than future date(current date + givenValue) 256 $days = $condition['value']-1; 257 $value = date('Y-m-d', strtotime('+'.$days.' days')); 258 break; 259 260 case 'days ago' : 261 $days = $condition['value']; 262 $value = date('Y-m-d', strtotime('-'.$days.' days')); 263 break; 264 265 case 'days later' : 266 $days = $condition['value']; 267 $value = date('Y-m-d', strtotime('+'.$days.' days')); 268 break; 269 270 case 'is today' : 271 $value = date('Y-m-d'); 272 break; 273 274 case 'less than hours before' : 275 $hours = $condition['value']; 276 $value = date('Y-m-d H:i:s', strtotime('-'.$hours.' hours')).','.date('Y-m-d H:i:s'); 277 break; 278 279 case 'less than hours later' : 280 $hours = $condition['value']; 281 $value = date('Y-m-d H:i:s').','.date('Y-m-d H:i:s', strtotime('+'.$hours.' hours')); 282 break; 283 284 case 'more than hours later' : 285 $hours = $condition['value']; 286 $value = date('Y-m-d H:i:s', strtotime('+'.$hours.' hours')); 287 break; 288 289 case 'more than hours before' : 290 $hours = $condition['value']; 291 $value = date('Y-m-d H:i:s', strtotime('-'.$hours.' hours')); 292 break; 293 } 294 @date_default_timezone_set($default_timezone); 295 return $value; 296 } 297 298 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 20:08:37 2014 | Cross-referenced by PHPXref 0.7.1 |