[ Index ]

PHP Cross Reference of vtigercrm-6.1.0

title

Body

[close]

/modules/com_vtiger_workflow/ -> WorkFlowScheduler.php (source)

   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  }


Generated: Fri Nov 28 20:08:37 2014 Cross-referenced by PHPXref 0.7.1