[ Index ]

PHP Cross Reference of vtigercrm-6.1.0

title

Body

[close]

/modules/Settings/MailConverter/handlers/ -> MailScannerRule.php (source)

   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   ********************************************************************************/
  11  
  12  require_once ('modules/Settings/MailConverter/handlers/MailScannerAction.php');
  13  
  14  /**
  15   * Scanner Rule
  16   */
  17  class Vtiger_MailScannerRule {
  18      // id of this instance
  19      var $ruleid    = false;
  20      // scanner to which this rule is linked
  21      var $scannerid = false;
  22      // from address criteria
  23      var $fromaddress= false;
  24      // to address criteria
  25      var $toaddress = false;
  26      // cc address criteria
  27      var $cc = false;
  28      // bcc address criteria
  29      var $bcc = false;
  30      // subject criteria operator
  31      var $subjectop = false;
  32      // subject criteria
  33      var $subject   = false;
  34      // body criteria operator
  35      var $bodyop    = false;
  36      // body criteria
  37      var $body      = false;
  38      // order of this rule
  39      var $sequence  = false;
  40      // is this action valid
  41      var $isvalid   = false;
  42      // match criteria ALL or ANY
  43      var $matchusing = false;
  44      // assigned to user id
  45      var $assigned_to = false;
  46      // associated actions for this rule
  47      var $actions  = false;
  48      // TODO we are restricting one action for one rule right now
  49      var $useaction= false;
  50  
  51      /** DEBUG functionality **/
  52      var $debug     = false;
  53      function log($message) {
  54      global $log;
  55          if($log && $this->debug) { $log->debug($message); }
  56          else if($this->debug) echo "$message\n";
  57      }
  58  
  59      /**
  60       * Constructor
  61       */
  62      function __construct($forruleid) {
  63          $this->initialize($forruleid);
  64      }
  65  
  66      /**
  67       * String representation of this instance
  68       */
  69      function __toString() {
  70          $tostring = '';
  71          $tostring .= "FROM $this->fromaddress, TO $this->toaddress, CC $this->cc, BCC $this->bcc";
  72          $tostring .= ",SUBJECT $this->subjectop $this->subject, BODY $this->bodyop $this->body, MATCH USING, $this->matchusing";
  73          return $tostring;
  74      }
  75  
  76      /**
  77       * Initialize this instance
  78       */
  79      function initialize($forruleid) {
  80          global $adb;
  81          $result = $adb->pquery("SELECT * FROM vtiger_mailscanner_rules WHERE ruleid=? ORDER BY sequence", Array($forruleid));
  82  
  83          if ($adb->num_rows($result)) {
  84              $this->ruleid = $adb->query_result($result, 0, 'ruleid');
  85              $this->scannerid = $adb->query_result($result, 0, 'scannerid');
  86              $this->fromaddress = $adb->query_result($result, 0, 'fromaddress');
  87              $this->toaddress = $adb->query_result($result, 0, 'toaddress');
  88              $this->cc = $adb->query_result($result, 0, 'cc');
  89              $this->bcc = $adb->query_result($result, 0, 'bcc');
  90              $this->subjectop = $adb->query_result($result, 0, 'subjectop');
  91              $this->subject = $adb->query_result($result, 0, 'subject');
  92              $this->bodyop = $adb->query_result($result, 0, 'bodyop');
  93              $this->body = $adb->query_result($result, 0, 'body');
  94              $this->sequence = $adb->query_result($result, 0, 'sequence');
  95              $this->matchusing = $adb->query_result($result, 0, 'matchusing');
  96              $this->assigned_to = $adb->query_result($result, 0, 'assigned_to');
  97              $this->isvalid = true;
  98              $this->initializeActions();
  99              // At present we support only one action for a rule
 100                  if(!empty($this->actions)) $this->useaction = $this->actions[0];
 101          }
 102      }
 103  
 104      /**
 105       * Initialize the actions
 106       */
 107      function initializeActions() {
 108          global $adb;
 109              if($this->ruleid) {
 110              $this->actions = Array();
 111                  $actionres = $adb->pquery("SELECT actionid FROM vtiger_mailscanner_ruleactions WHERE ruleid=?",Array($this->ruleid));
 112              $actioncount = $adb->num_rows($actionres);
 113                  if($actioncount) {
 114                      for($index = 0; $index < $actioncount; ++$index) {
 115                  $actionid = $adb->query_result($actionres, $index, 'actionid');
 116                  $ruleaction = new Vtiger_MailScannerAction($actionid);
 117                  $ruleaction->debug = $this->debug;
 118                  $this->actions[] = $ruleaction;
 119              }
 120              }
 121          }
 122      }
 123  
 124      /**
 125       * Is body rule defined?
 126       */
 127      function hasBodyRule() {
 128          return (!empty($this->bodyop));
 129      }
 130  
 131      /**
 132       * Check if the rule criteria is matching
 133       */
 134  	function isMatching($matchfound1, $matchfound2 = null) {
 135          if ($matchfound2 === null)
 136              return $matchfound1;
 137  
 138          if ($this->matchusing == 'AND')
 139              return ($matchfound1 && $matchfound2);
 140          if ($this->matchusing == 'OR')
 141              return ($matchfound1 || $matchfound2);
 142          return false;
 143      }
 144  
 145      /**
 146       * Apply all the criteria.
 147       * @param $mailrecord
 148       * @param $includingBody
 149       * @returns false if not match is found or else all matching result found
 150       */
 151      function applyAll($mailrecord, $includingBody=true) {
 152          $matchresults = Array();
 153          $matchfound = null;
 154  
 155          if ($this->hasACondition()) {
 156              $subrules = Array('FROM', 'TO', 'CC', 'BCC', 'SUBJECT', 'BODY');
 157  
 158              foreach ($subrules as $subrule) {
 159              // Body rule could be defered later to improve performance
 160              // in that case skip it.
 161                      if($subrule == 'BODY' && !$includingBody) continue;
 162  
 163              $checkmatch = $this->apply($subrule, $mailrecord);
 164              $matchfound = $this->isMatching($checkmatch, $matchfound);
 165              // Collect matching result array
 166              if ($matchfound && is_array($checkmatch))
 167                  $matchresults[] = $checkmatch;
 168              }
 169          } else {
 170              $matchfound = false;
 171                  if($this->matchusing == 'OR') {
 172              $matchfound = true;
 173                      $matchresults[] = $this->__CreateMatchResult('BLANK','','','');
 174              }
 175          }
 176          return ($matchfound)? $matchresults : false;
 177      }
 178  
 179      /**
 180       * Check if at least one condition is set for this rule.
 181       */
 182      function hasACondition() {
 183          $hasFromAddress = $this->fromaddress ? true : false;
 184          $hasToAddress = $this->toaddress ? true : false;
 185          $hasCcAddress = $this->cc ? true : false;
 186          $hasBccAddress = $this->bcc ? true : false;
 187          $hasSubjectOp = $this->subjectop ? true : false;
 188          $hasBodyOp = $this->bodyop ? true : false;
 189          return ($hasFromAddress || $hasToAddress || $hasCcAddress || $hasBccAddress || $hasSubjectOp || $hasBodyOp);
 190      }
 191  
 192      /**
 193       * Apply required condition on the mail record.
 194       */
 195      function apply($subrule, $mailrecord) {
 196          $matchfound = false;
 197              if($this->isvalid) {
 198                  switch(strtoupper($subrule)) {
 199              case 'FROM':
 200                  if($this->fromaddress) {
 201                      if(strpos($this->fromaddress, '*') == 0)
 202                          $this->fromaddress = trim($this->fromaddress, '*');
 203                      $matchfound = $this->find($subrule, 'Contains', $mailrecord->_from[0], $this->fromaddress);
 204                  } else {
 205                      $matchfound = $this->__CreateDefaultMatchResult($subrule);
 206                  }
 207                  break;
 208              case 'TO':
 209                          if($this->toaddress) {
 210                              foreach($mailrecord->_to as $toemail) {
 211                      $matchfound = $this->find($subrule, 'Contains', $toemail, $this->toaddress);
 212                                  if($matchfound) break;
 213                  }
 214                  } else {
 215                  $matchfound = $this->__CreateDefaultMatchResult($subrule);
 216                  }
 217                  break;
 218              case 'CC':
 219                  if ($this->cc) {
 220                  foreach ($mailrecord->_cc as $toemail) {
 221                      $matchfound = $this->find($subrule, 'Contains', $toemail, $this->cc);
 222                      if ($matchfound)
 223                      break;
 224                  }
 225                  } else {
 226                  $matchfound = $this->__CreateDefaultMatchResult($subrule);
 227                  }
 228                  break;
 229              case 'BCC':
 230                  if ($this->bcc) {
 231                  foreach ($mailrecord->_bcc as $toemail) {
 232                      $matchfound = $this->find($subrule, 'Contains', $toemail, $this->bcc);
 233                      if ($matchfound)
 234                      break;
 235                  }
 236                  } else {
 237                  $matchfound = $this->__CreateDefaultMatchResult($subrule);
 238                  }
 239                  break;
 240              case 'SUBJECT':
 241                  if ($this->subjectop) {
 242                      $matchfound = $this->find($subrule, $this->subjectop, $mailrecord->_subject, $this->subject);
 243                  } else {
 244                      $matchfound = $this->__CreateDefaultMatchResult($subrule);
 245                  }
 246                  break;
 247              case 'BODY':
 248                  if ($this->bodyop) {
 249                  $matchfound = $this->find($subrule, $this->bodyop, trim(strip_tags($mailrecord->_body)), trim($this->body));
 250                  } else {
 251                  $matchfound = $this->__CreateDefaultMatchResult($subrule);
 252                  }
 253                  break;
 254              }
 255          }
 256          return $matchfound;
 257      }
 258  
 259      /**
 260       * Find if the rule matches based on condition and parameters
 261       */
 262      function find($subrule, $condition, $input, $searchfor) {
 263          if (!$input)
 264              return false;
 265              $input = trim(preg_replace("/\r/", '', decode_html($input))); 
 266              $searchfor = decode_html($searchfor);
 267          $matchfound = false;
 268          $matches = false;
 269  
 270          switch ($condition) {
 271              case 'Contains':
 272              $matchfound = stripos($input, $searchfor);
 273              $matchfound = ($matchfound !== FALSE);
 274              $matches = $searchfor;
 275              break;
 276              case 'Not Contains':
 277              $matchfound = stripos($input, $searchfor);
 278              $matchfound = ($matchfound === FALSE);
 279              $matches = $searchfor;
 280              break;
 281              case 'Equals':
 282              $matchfound = strcasecmp($input, $searchfor);
 283              $matchfound = ($matchfound === 0);
 284              $matches = $searchfor;
 285              break;
 286              case 'Not Equals':
 287              $matchfound = strcasecmp($input, $searchfor);
 288              $matchfound = ($matchfound !== 0);
 289              $matches = $searchfor;
 290              break;
 291              case 'Begins With':
 292              $matchfound = stripos($input, $searchfor);
 293              $matchfound = ($matchfound === 0);
 294              $matches = $searchfor;
 295              break;
 296              case 'Ends With':
 297              $matchfound = strripos($input, $searchfor);
 298              $matchfound = ($matchfound === strlen($input) - strlen($searchfor));
 299              $matches = $searchfor;
 300              break;
 301              case 'Regex':
 302              $regmatches = Array();
 303              $matchfound = false;
 304              $searchfor = str_replace('/', '\/', $searchfor);
 305                      $input = str_replace("_", " ", $input);
 306              if (preg_match("/$searchfor/i", $input, $regmatches)) {
 307                  // Pick the last matching group
 308                  $matches = $regmatches[count($regmatches) - 1];
 309                  $matchfound = true;
 310              }
 311              break;
 312              case 'Has Ticket Number':
 313              $regmatches = Array();
 314              $matchfound = false;
 315              $searchfor = "^Ticket Id[^:]?: ([0-9]+)$";
 316              $searchfor = str_replace('/', '\/', $searchfor);
 317              if (preg_match("/$searchfor/i", $input, $regmatches)) {
 318                  // Pick the last matching group
 319                  $matches = $regmatches[count($regmatches) - 1];
 320                  $matchfound = true;
 321              }
 322              break;
 323          }
 324          if($matchfound) $matchfound = $this->__CreateMatchResult($subrule, $condition, $searchfor, $matches);
 325          return $matchfound;
 326      }
 327  
 328      /**
 329       * Create matching result for the subrule.
 330       */
 331      function __CreateMatchResult($subrule, $condition, $searchfor, $matches) {
 332          return Array( 'subrule' => $subrule, 'condition' => $condition, 'searchfor' => $searchfor, 'matches' => $matches);
 333      }
 334  
 335      /**
 336       * Create default success matching result
 337       */
 338      function __CreateDefaultMatchResult($subrule) {
 339          if($this->matchusing == 'OR') return false;
 340          if($this->matchusing == 'AND') return $this->__CreateMatchResult($subrule, 'Contains', '', '');
 341      }
 342  
 343      /**
 344       * Detect if the rule match result has Regex condition
 345       * @param $matchresult result of apply obtained earlier
 346       * @returns matchinfo if Regex match is found, false otherwise
 347       */
 348      function hasRegexMatch($matchresult) {
 349          foreach($matchresult as $matchinfo) {
 350              $match_condition = $matchinfo['condition'];
 351              $match_string = $matchinfo['matches'];
 352                  if($match_condition == 'Regex' && $match_string)
 353              return $matchinfo;
 354          }
 355          return false;
 356      }
 357  
 358      /**
 359       * Swap (reset) sequence of two rules.
 360       */
 361      static function resetSequence($ruleid1, $ruleid2) {
 362          global $adb;
 363              $ruleresult = $adb->pquery("SELECT ruleid, sequence FROM vtiger_mailscanner_rules WHERE ruleid = ? or ruleid = ?",
 364                  Array($ruleid1, $ruleid2));
 365          $rule_partinfo = Array();
 366              if($adb->num_rows($ruleresult) != 2) {
 367              return false;
 368          } else {
 369              $rule_partinfo[$adb->query_result($ruleresult, 0, 'ruleid')] = $adb->query_result($ruleresult, 0, 'sequence');
 370              $rule_partinfo[$adb->query_result($ruleresult, 1, 'ruleid')] = $adb->query_result($ruleresult, 1, 'sequence');
 371              $adb->pquery("UPDATE vtiger_mailscanner_rules SET sequence = ? WHERE ruleid = ?", Array($rule_partinfo[$ruleid2], $ruleid1));
 372              $adb->pquery("UPDATE vtiger_mailscanner_rules SET sequence = ? WHERE ruleid = ?", Array($rule_partinfo[$ruleid1], $ruleid2));
 373          }
 374      }
 375  
 376      /**
 377       * Update rule information in database.
 378       */
 379      function update() {
 380          global $adb;
 381          if ($this->ruleid) {
 382              $adb->pquery("UPDATE vtiger_mailscanner_rules SET scannerid=?,fromaddress=?,toaddress=?,subjectop=?,subject=?,bodyop=?,body=?,matchusing=?,assigned_to=?,cc=?,bcc=?
 383                      WHERE ruleid=?", Array($this->scannerid, $this->fromaddress, $this->toaddress, $this->subjectop, $this->subject,
 384              $this->bodyop, $this->body, $this->matchusing, $this->assigned_to, $this->cc, $this->bcc, $this->ruleid));
 385          } else {
 386              $this->sequence = $this->__nextsequence();
 387              $adb->pquery("INSERT INTO vtiger_mailscanner_rules(scannerid,fromaddress,toaddress,subjectop,subject,bodyop,body,matchusing,sequence,assigned_to,cc,bcc)
 388                      VALUES(?,?,?,?,?,?,?,?,?,?,?,?)", Array($this->scannerid, $this->fromaddress, $this->toaddress, $this->subjectop, $this->subject,
 389              $this->bodyop, $this->body, $this->matchusing, $this->sequence, $this->assigned_to, $this->cc, $this->bcc));
 390              $this->ruleid = $adb->database->Insert_ID();
 391          }
 392      }
 393  
 394      /**
 395       * Get next sequence to use
 396       */
 397      function __nextsequence() {
 398          global $adb;
 399          $seqres = $adb->pquery("SELECT max(sequence) AS max_sequence FROM vtiger_mailscanner_rules", Array());
 400          $maxsequence = 0;
 401              if($adb->num_rows($seqres)) {
 402              $maxsequence = $adb->query_result($seqres, 0, 'max_sequence');
 403          }
 404          ++$maxsequence;
 405          return $maxsequence;
 406      }
 407  
 408      /**
 409       * Delete the rule and associated information.
 410       */
 411      function delete() {
 412          global $adb;
 413  
 414          // Delete dependencies
 415              if(!empty($this->actions)) {
 416                  foreach($this->actions as $action) {
 417              $action->delete();
 418              }
 419          }
 420              if($this->ruleid) {
 421              $adb->pquery("DELETE FROM vtiger_mailscanner_ruleactions WHERE ruleid = ?", Array($this->ruleid));
 422              $adb->pquery("DELETE FROM vtiger_mailscanner_rules WHERE ruleid=?", Array($this->ruleid));
 423          }
 424      }
 425  
 426      /**
 427       * Update action linked to the rule.
 428       */
 429      function updateAction($actionid, $actiontext) {
 430          $action = $this->useaction;
 431  
 432              if($actionid != '' && $actiontext == '') {
 433                  if($action) $action->delete();
 434          } else {
 435                  if($actionid == '') {
 436              $action = new Vtiger_MailScannerAction($actionid);
 437              }
 438              $action->scannerid = $this->scannerid;
 439              $action->update($this->ruleid, $actiontext);
 440          }
 441      }
 442  
 443      /**
 444       * Take action on mail record
 445       */
 446      function takeAction($mailscanner, $mailrecord, $matchresult) {
 447          if(empty($this->actions)) return false;
 448  
 449          $action = $this->useaction; // Action is limited to One right now
 450          return $action->apply($mailscanner, $mailrecord, $this, $matchresult);
 451      }
 452  
 453  }
 454  
 455  ?>


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