vendor/uvdesk/automation-bundle/EventListener/WorkflowListener.php line 91

Open in your IDE?
  1. <?php
  2. namespace Webkul\UVDesk\AutomationBundle\EventListener;
  3. use Doctrine\ORM\EntityManagerInterface;
  4. use Symfony\Component\DependencyInjection\ContainerInterface;
  5. use Webkul\UVDesk\AutomationBundle\Entity\Workflow;
  6. use Webkul\UVDesk\AutomationBundle\Workflow\Action;
  7. use Webkul\UVDesk\AutomationBundle\Workflow\Event;
  8. use Webkul\UVDesk\AutomationBundle\Workflow\Events as WorkflowEvents;
  9. use Webkul\UVDesk\CoreFrameworkBundle\Entity\Ticket;
  10. use Webkul\UVDesk\CoreFrameworkBundle\Services\TicketService;
  11. use Webkul\UVDesk\CoreFrameworkBundle\Services\UserService;
  12. use UVDesk\CommunityPackages\UVDesk as UVDeskCommunityPackages;
  13. use Webkul\UVDesk\CoreFrameworkBundle\Workflow\Events as CoreWorkflowEvents;
  14. class WorkflowListener
  15. {
  16.     private $container;
  17.     private $entityManager;
  18.     private $ticketService;
  19.     private $userService;
  20.     private $registeredWorkflowEvents = [];
  21.     private $registeredWorkflowActions = [];
  22.     public function __construct(ContainerInterface $containerEntityManagerInterface $entityManagerTicketService $ticketServiceUserService $userService)
  23.     {
  24.         $this->container $container;
  25.         $this->entityManager $entityManager;
  26.         $this->ticketService $ticketService;
  27.         $this->userService $userService;
  28.     }
  29.     public function registerWorkflowEvent(Event $serviceTag)
  30.     {
  31.         $this->registeredWorkflowEvents[] = $serviceTag;
  32.     }
  33.     public function registerWorkflowAction(Action $serviceTag)
  34.     {
  35.         $this->registeredWorkflowActions[] = $serviceTag;
  36.     }
  37.     public function getRegisteredWorkflowEvent($eventId)
  38.     {
  39.         foreach ($this->registeredWorkflowEvents as $workflowDefinition) {
  40.             if ($workflowDefinition->getId() == $eventId) {
  41.                 return $workflowDefinition;
  42.             }
  43.         }
  44.         return null;
  45.     }
  46.     
  47.     public function getRegisteredWorkflowEvents()
  48.     {
  49.         return $this->registeredWorkflowEvents;
  50.     }
  51.     public function getRegisteredWorkflowActions()
  52.     {
  53.         return $this->registeredWorkflowActions;
  54.     }
  55.     public function executeReplyEvent(Event $event) {
  56.         if ($this->userService->isFileExists('apps/uvdesk/report')) {
  57.             $reportServiceClass UVDeskCommunityPackages\Report\Services\ReportService::class;
  58.             $reportService = new $reportServiceClass($this->entityManager$this->container$this->ticketService$this->userService);
  59.             if (($event) instanceof CoreWorkflowEvents\Ticket\Status) {
  60.                 $reportService->calculateResolveTime($event->getTicket());
  61.             } else if (
  62.                 ($event) instanceof CoreWorkflowEvents\Ticket\AgentReply    ||
  63.                 ($event) instanceof CoreWorkflowEvents\Ticket\CustomerReply ||
  64.                 ($event) instanceof CoreWorkflowEvents\Ticket\CollaboratorReply
  65.             ) {
  66.                 $thread $event->getThread();
  67.                 if (
  68.                     $thread 
  69.                     && $thread->getThreadType() == 'reply' 
  70.                     && ($thread->getCreatedBy() == 'agent' 
  71.                     || $thread->getCreatedBy() == 'customer')
  72.                 ) {
  73.                     $reportService->calculateResponseTime($thread);
  74.                 }
  75.             }
  76.         }
  77.     }
  78.     public function executeWorkflow($event)
  79.     {
  80.         if (! ($event instanceof Event))
  81.             return;
  82.         $workflowCollection $this->entityManager->getRepository(Workflow::class)->getEventWorkflows($event::getId());
  83.         if ((
  84.                 $event instanceof CoreWorkflowEvents\Ticket\Create 
  85.                 || $event instanceof CoreWorkflowEvents\Ticket\Priority
  86.             )
  87.             && $this->userService->isFileExists('apps/uvdesk/sla')
  88.         ) {
  89.             $slaServiceClass UVDeskCommunityPackages\SLA\Services\SlaService::class;
  90.             $slaService = new $slaServiceClass($this->container$this->entityManager );
  91.             $slaService->refreshTicketPolicies($event->getTicket());
  92.         }
  93.         if (($event) instanceof CoreWorkflowEvents\Ticket\Status) {
  94.             $this->executeReplyEvent($event);
  95.         }
  96.         if (empty($workflowCollection) && 'uvdesk.user.forgot_password' == $event::getId()) {
  97.             $user $event->getArgument('entity');
  98.             if (
  99.                 ! empty($user)
  100.                 && $user instanceof \Webkul\UVDesk\CoreFrameworkBundle\Entity\User
  101.             ) {
  102.                 $agentForgotPasswordWorkflows $this->entityManager->getRepository(Workflow::class)->getEventWorkflows('uvdesk.agent.forgot_password');
  103.                 $customerForgotPasswordWorkflows $this->entityManager->getRepository(Workflow::class)->getEventWorkflows('uvdesk.customer.forgot_password');
  104.                 if (!empty($agentForgotPasswordWorkflows) || !empty($customerForgotPasswordWorkflows)) {
  105.                     $agentInstance $user->getAgentInstance();
  106.                     $customerInstance $user->getCustomerInstance();
  107.                     if (
  108.                         ! empty($customerForgotPasswordWorkflows)
  109.                         && !empty($customerInstance)
  110.                     ) {
  111.                         // Resort to uvdesk.customer.forgot_password workflows
  112.                         $workflowCollection $customerForgotPasswordWorkflows;
  113.                     } else if (
  114.                         ! empty($agentForgotPasswordWorkflows)
  115.                         && !empty($agentInstance)
  116.                     ) {
  117.                         // Resort to uvdesk.agent.forgot_password workflows
  118.                         $workflowCollection $agentForgotPasswordWorkflows;
  119.                     }
  120.                 }
  121.             }
  122.         }
  123.         
  124.         if (! empty($workflowCollection)) {
  125.             foreach ($workflowCollection as $workflow) {
  126.                 $totalConditions 0;
  127.                 $totalEvaluatedConditions 0;
  128.                 foreach ($this->evaluateWorkflowConditions($workflow) as $workflowCondition) {
  129.                     $totalEvaluatedConditions++;
  130.                     if (isset($workflowCondition['type']) && $this->checkCondition($workflowCondition$event)) {
  131.                         $totalConditions++;
  132.                     }
  133.                     if (isset($workflowCondition['or'])) {
  134.                         foreach ($workflowCondition['or'] as $orCondition) {
  135.                             if ($this->checkCondition($orCondition$event)) {
  136.                                 $totalConditions++;
  137.                             }
  138.                         }
  139.                     }
  140.                 }
  141.                 if ($totalEvaluatedConditions == || $totalConditions >= $totalEvaluatedConditions) {
  142.                     $this->applyWorkflowActions($workflow$event);
  143.                 }
  144.             }
  145.         }
  146.     }
  147.     private function evaluateWorkflowConditions(Workflow $workflow)
  148.     {
  149.         $index = -1;
  150.         $workflowConditions = [];
  151.         if ($workflow->getConditions() == null) {
  152.             return $workflowConditions;
  153.         }
  154.         foreach ($workflow->getConditions() as $condition) {
  155.             if (
  156.                 ! empty($condition['operation'])
  157.                 && $condition['operation'] != "&&"
  158.             ) {
  159.                 if (!isset($finalConditions[$index]['or'])) {
  160.                     $finalConditions[$index]['or'] = [];
  161.                 }
  162.                 $workflowConditions[$index]['or'][] = $condition;
  163.             } else {
  164.                 $index++;
  165.                 $workflowConditions[] = $condition;
  166.             }
  167.         }
  168.         return $workflowConditions;
  169.     }
  170.     private function applyWorkflowActions(Workflow $workflowEvent $event)
  171.     {
  172.         foreach ($workflow->getActions() as $attributes) {
  173.             if (empty($attributes['type'])) {
  174.                 continue;
  175.             }
  176.             foreach ($this->getRegisteredWorkflowActions() as $workflowAction) {
  177.                 if ($workflowAction->getId() == $attributes['type']) {
  178.                     $workflowAction->applyAction($this->container$event, isset($attributes['value']) ? $attributes['value'] : '');
  179.                 }
  180.             }
  181.         }
  182.     }
  183.     public function checkCondition($conditionEvent $event)
  184.     {
  185.         $entity null;
  186.         switch (true) {
  187.             case $event instanceof WorkflowEvents\EmailActivity:
  188.                 $entity $event->getResolvedEmailHeaders();
  189.                 break;
  190.             case $event instanceof WorkflowEvents\TicketActivity:
  191.                 $entity $event->getTicket();
  192.                 break;
  193.             case $event instanceof WorkflowEvents\AgentActivity:
  194.             case $event instanceof WorkflowEvents\CustomerActivity:
  195.             case $event instanceof WorkflowEvents\UserActivity:
  196.                 $entity $event->getUser();
  197.                 break;
  198.             default:
  199.                 break;
  200.         }
  201.         if (empty($entity)) {
  202.             return false;
  203.         }
  204.         switch ($condition['type']) {
  205.             case 'from_mail':
  206.                 if (isset($condition['value'])) {
  207.                     if ($entity instanceof Ticket) {
  208.                         return $this->match($condition['match'], $entity->getCustomer()->getEmail(), $condition['value']);
  209.                     } else if (
  210.                         is_array($entity
  211.                         && ! empty($entity['from'])
  212.                     ) {
  213.                         return $this->match($condition['match'], $entity['from'], $condition['value']);
  214.                     }
  215.                 }
  216.                 break;
  217.             case 'to_mail':
  218.                 if (
  219.                     isset($condition['value'])
  220.                     && $entity instanceof Ticket
  221.                     && $entity->getMailboxEmail()
  222.                 ) {
  223.                     return $this->match($condition['match'], $entity->getMailboxEmail(), $condition['value']);
  224.                 }
  225.                 break;
  226.             case 'subject':
  227.                 if (
  228.                     isset($condition['value'])
  229.                     && ($entity instanceof Ticket || $entity instanceof Task)
  230.                 ) {
  231.                     return $this->match($condition['match'], $entity->getSubject(), $condition['value']);
  232.                 }
  233.                 break;
  234.             case 'description':
  235.                 if (
  236.                     isset($condition['value'])
  237.                     && $entity instanceof Ticket
  238.                 ) {
  239.                     $reply $entity->createdThread->getMessage();
  240.                     $reply rtrim(strip_tags($reply), "\n" );
  241.                     return $this->match($condition['match'], rtrim($reply), $condition['value']);
  242.                 }
  243.                 break;
  244.             case 'subject_or_description':
  245.                 if (
  246.                     isset($condition['value'])
  247.                     && $entity instanceof Ticket
  248.                 ) {
  249.                     $flag $this->match($condition['match'], $entity->getSubject(), $condition['value']);
  250.                     $createThread $this->container->get('ticket.service')->getCreateReply($entity->getId(),false);
  251.                     if (! $flag) {
  252.                         $createThread $this->container->get('ticket.service')->getCreateReply($entity->getId(),false);
  253.                         $createThread['reply'] = rtrim(strip_tags($createThread['reply']), "\n" );
  254.                         $flag $this->match($condition['match'],$createThread['reply'],$condition['value']);
  255.                     }
  256.                     return $flag;
  257.                 }
  258.                 break;
  259.             case 'TicketPriority':
  260.                 if (
  261.                     isset($condition['value'])
  262.                     && ($entity instanceof Ticket)
  263.                 ) {
  264.                     return $this->match($condition['match'], $entity->getPriority()->getId(), $condition['value']);
  265.                 }
  266.                 break;
  267.             case 'TicketType':
  268.                 if (
  269.                     isset($condition['value'])
  270.                     && $entity instanceof Ticket
  271.                 ) {
  272.                     $typeId $entity->getType() ? $entity->getType()->getId() : 0;
  273.                     return $this->match($condition['match'], $typeId$condition['value']);
  274.                 }
  275.                 break;
  276.             case 'TicketStatus':
  277.                 if (
  278.                     isset($condition['value'])
  279.                     && $entity instanceof Ticket
  280.                 ) {
  281.                     return $this->match($condition['match'], $entity->getStatus()->getId(), $condition['value']);
  282.                 }
  283.                 break;
  284.             case 'stage':
  285.                 if (
  286.                     isset($condition['value'])
  287.                     && $entity instanceof Task
  288.                 ) {
  289.                     return $this->match($condition['match'], $entity->getStage()->getId(), $condition['value']);
  290.                 }
  291.                 break;
  292.             case 'source':
  293.                 if (
  294.                     isset($condition['value'])
  295.                     && $entity instanceof Ticket
  296.                 ) {
  297.                     return $this->match($condition['match'], $entity->getSource(), $condition['value']);
  298.                 }
  299.                 break;
  300.             case 'created':
  301.                 if (
  302.                     isset($condition['value']) 
  303.                     && ($entity instanceof Ticket || $entity instanceof Task)
  304.                 ) {
  305.                     $date date_format($entity->getCreatedAt(), "d-m-Y h:ia");
  306.                     return $this->match($condition['match'], $date$condition['value']);
  307.                 }
  308.                 break;
  309.             case 'agent':
  310.                 if (
  311.                     isset($condition['value'])
  312.                     && $entity instanceof Ticket
  313.                     && $entity->getAgent()
  314.                 ) {
  315.                     return $this->match($condition['match'], $entity->getAgent()->getId(), (($condition['value'] == 'actionPerformingAgent') ? ($this->container->get('user.service')->getCurrentUser() ? $this->container->get('user.service')->getCurrentUser()->getId() : 0) : $condition['value']));
  316.                 }
  317.                 break;
  318.             case 'group':
  319.                 if (
  320.                     isset($condition['value'])
  321.                     && $entity instanceof Ticket
  322.                 ) {
  323.                     $groupId $entity->getSupportGroup() ? $entity->getSupportGroup()->getId() : 0;
  324.                     return $this->match($condition['match'], $groupId$condition['value']);
  325.                 }
  326.                 break;
  327.             case 'team':
  328.                 if (
  329.                     isset($condition['value'])
  330.                     && $entity instanceof Ticket
  331.                 ) {
  332.                     $subGroupId $entity->getSupportTeam() ? $entity->getSupportTeam()->getId() : 0;
  333.                     return $this->match($condition['match'], $subGroupId$condition['value']);
  334.                 }
  335.                 break;
  336.             case 'customer_name':
  337.                 if (
  338.                     isset($condition['value'])
  339.                     && $entity instanceof Ticket
  340.                 ) { 
  341.                     return $this->match($condition['match'], $entity->getCustomer()->getFullName(), $condition['value']);
  342.                 }
  343.                 
  344.                 break;
  345.             case 'customer_email':
  346.                 if (
  347.                     isset($condition['value'])
  348.                     && $entity instanceof Ticket
  349.                 ) {
  350.                     return $this->match($condition['match'], $entity->getCustomer()->getEmail(), $condition['value']);
  351.                 }
  352.                 break;
  353.             case strpos($condition['type'], 'customFields') == 0:
  354.                 $value null;
  355.                 $ticketCfValues $entity->getCustomFieldValues()->getValues();
  356.                 
  357.                 foreach ($ticketCfValues as $cfValue) {
  358.                     $mainCf $cfValue->getTicketCustomFieldsValues();
  359.                     
  360.                     if ($condition['type'] == 'customFields[' $mainCf->getId() . ']' ) {
  361.                         if (in_array($mainCf->getFieldType(), ['select''radio''checkbox'])) {
  362.                            $value json_decode($cfValue->getValue(), true);
  363.                         } else {
  364.                            $value trim($cfValue->getValue(), '"');
  365.                         }
  366.                         
  367.                         break;
  368.                     }
  369.                 }
  370.                 if (
  371.                     isset($condition['value'])
  372.                     && $entity instanceof Ticket
  373.                 ) {
  374.                     return $this->match($condition['match'], !empty($value) ? $value ''$condition['value']);
  375.                 }
  376.                 break;
  377.             default:
  378.                 break;
  379.         }
  380.         return false;
  381.     }
  382.     public function match($condition$haystack$needle)
  383.     {
  384.         // Filter tags
  385.         if ('string' == gettype($haystack)) {
  386.             $haystack strip_tags($haystack);
  387.         }
  388.         switch ($condition) {
  389.             case 'is':
  390.                 return is_array($haystack) ? in_array($needle$haystack) : $haystack == $needle;
  391.             case 'isNot':
  392.                 return is_array($haystack) ? !in_array($needle$haystack) : $haystack != $needle;
  393.             case 'contains':
  394.                 return strripos($haystack,$needle) !== false true false;
  395.             case 'notContains':
  396.                 return strripos($haystack,$needle) === false true false;
  397.             case 'startWith':
  398.                 return $needle === "" || strripos($haystack$needle, -strlen($haystack)) !== FALSE;
  399.             case 'endWith':
  400.                 return $needle === "" || (($temp strlen($haystack) - strlen($needle)) >= && stripos($haystack$needle$temp) !== FALSE);
  401.             case 'before':
  402.                 $createdTimeStamp date('Y-m-d'strtotime($haystack));
  403.                 $conditionTimeStamp date('Y-m-d'strtotime($needle " 23:59:59"));
  404.                 return $createdTimeStamp $conditionTimeStamp true false;
  405.             case 'beforeOn':
  406.                 $createdTimeStamp date('Y-m-d'strtotime($haystack));
  407.                 $conditionTimeStamp date('Y-m-d'strtotime($needle " 23:59:59"));
  408.                 return ($createdTimeStamp $conditionTimeStamp || $createdTimeStamp == $conditionTimeStamp) ? true false;
  409.             case 'after':
  410.                 $createdTimeStamp date('Y-m-d'strtotime($haystack));
  411.                 $conditionTimeStamp date('Y-m-d'strtotime($needle " 23:59:59"));
  412.                 return $createdTimeStamp $conditionTimeStamp true false;
  413.             case 'afterOn':
  414.                 $createdTimeStamp date('Y-m-d'strtotime($haystack));
  415.                 $conditionTimeStamp date('Y-m-d'strtotime($needle " 23:59:59"));
  416.                 
  417.                 return $createdTimeStamp $conditionTimeStamp || $createdTimeStamp == $conditionTimeStamp true false;
  418.             case 'beforeDateTime':
  419.                 $createdTimeStamp date('Y-m-d h:i:s'strtotime($haystack));
  420.                 $conditionTimeStamp date('Y-m-d h:i:s'strtotime($needle));
  421.                 return $createdTimeStamp $conditionTimeStamp true false;
  422.             case 'beforeDateTimeOn':
  423.                 $createdTimeStamp date('Y-m-d h:i:s'strtotime($haystack));
  424.                 $conditionTimeStamp date('Y-m-d h:i:s'strtotime($needle));
  425.                 return ($createdTimeStamp $conditionTimeStamp || $createdTimeStamp == $conditionTimeStamp) ? true false;
  426.             case 'afterDateTime':
  427.                 $createdTimeStamp date('Y-m-d h:i:s'strtotime($haystack));
  428.                 $conditionTimeStamp date('Y-m-d h:i:s'strtotime($needle));
  429.                 return $createdTimeStamp $conditionTimeStamp true false;
  430.             case 'afterDateTimeOn':
  431.                 $createdTimeStamp date('Y-m-d h:i:s'strtotime($haystack));
  432.                 $conditionTimeStamp date('Y-m-d h:i:s'strtotime($needle));
  433.                 return $createdTimeStamp $conditionTimeStamp || $createdTimeStamp == $conditionTimeStamp true false;
  434.             case 'beforeTime':
  435.                 $createdTimeStamp date('Y-m-d H:i A'strtotime('2017-01-01' $haystack));
  436.                 $conditionTimeStamp date('Y-m-d H:i A'strtotime('2017-01-01' $needle));
  437.                 return $createdTimeStamp $conditionTimeStamp true false;
  438.             case 'beforeTimeOn':
  439.                 $createdTimeStamp date('Y-m-d H:i A'strtotime('2017-01-01' $haystack));
  440.                 $conditionTimeStamp date('Y-m-d H:i A'strtotime('2017-01-01' $needle));
  441.                 return ($createdTimeStamp $conditionTimeStamp || $createdTimeStamp == $conditionTimeStamp) ? true false;
  442.             case 'afterTime':
  443.                 $createdTimeStamp date('Y-m-d H:i A'strtotime('2017-01-01' $haystack));
  444.                 $conditionTimeStamp date('Y-m-d H:i A'strtotime('2017-01-01' $needle));
  445.                 return $createdTimeStamp $conditionTimeStamp true false;
  446.             case 'afterTimeOn':
  447.                 $createdTimeStamp date('Y-m-d H:i A'strtotime('2017-01-01' $haystack));
  448.                 $conditionTimeStamp date('Y-m-d H:i A'strtotime('2017-01-01' $needle));
  449.                 return $createdTimeStamp $conditionTimeStamp || $createdTimeStamp == $conditionTimeStamp true false;
  450.             case 'greaterThan':
  451.                 return !is_array($haystack) && $needle $haystack;
  452.             case 'lessThan':
  453.                 return !is_array($haystack) && $needle $haystack;
  454.             default:
  455.                 break;
  456.         }
  457.         return false;
  458.     }
  459. }