apps/uvdesk/custom-fields/src/Services/CustomFieldsService.php line 46

Open in your IDE?
  1. <?php
  2. namespace UVDesk\CommunityPackages\UVDesk\CustomFields\Services;
  3. use Doctrine\ORM\EntityManagerInterface;
  4. use Symfony\Component\DependencyInjection\ContainerInterface;
  5. use Symfony\Component\HttpFoundation\Request;
  6. use Symfony\Contracts\Translation\TranslatorInterface;
  7. use UVDesk\CommunityPackages\UVDesk\CustomFields\EntityCustomFields;
  8. use UVDesk\CommunityPackages\UVDesk\CustomFields\Entity\CustomFields;
  9. use UVDesk\CommunityPackages\UVDesk\CustomFields\Entity\TicketCustomFieldsValues;
  10. use Webkul\UVDesk\CoreFrameworkBundle\Entity\Attachment;
  11. use Webkul\UVDesk\CoreFrameworkBundle\Entity\Ticket;
  12. use Webkul\UVDesk\CoreFrameworkBundle\Entity\TicketType;
  13. use Webkul\UVDesk\CoreFrameworkBundle\Services\UserService;
  14. class CustomFieldsService
  15. {
  16.     CONST DEFAULT_VALIDATION_RULES = [
  17.         "fieldtype" => "text"
  18.         "minNo" => ""
  19.         "maxNo" => ""
  20.         "allowedDomain" => ""
  21.         "restrictedDomain" => ""
  22.         "maxFileSize" => ""
  23.         "regex" => ""
  24.         "restrictedDomain" => ""
  25.     ];
  26.     private $entityManager null;
  27.     private $customContainer null;
  28.     private $validationService null;
  29.     private $translatorService null;
  30.     public function __construct(
  31.         EntityManagerInterface $entityManager
  32.         ContainerInterface $customContainer
  33.         ValidationService $validationService,
  34.         TranslatorInterface $translatorService
  35.         UserService $userService
  36.     ) {
  37.         $this->entityManager $entityManager;
  38.         $this->customContainer $customContainer;
  39.         $this->validationService $validationService;
  40.         $this->translatorService $translatorService;
  41.         $this->userService $userService;
  42.     }
  43.     /**
  44.     * customFieldValidation for Ticket, used in 1.TicketBundle, 2. SupportCenterBundle 3.ApiBundle
  45.     *
  46.     * @param Request $request
  47.     * @param String $userType (optional) (like for user, customer, both)
  48.     *
  49.     * @return Array with keys: 'errorMain', 'formErrors', 'errorFlashMessage'
  50.     */
  51.     public function customFieldsValidation(Request $request$userType 'both')
  52.     {
  53.         $errorMain false;
  54.         $formErrors = [];
  55.         $errorFlashMessage null;
  56.         $data $request->request->all() ? : json_decode($request->getContent(), true);
  57.         
  58.         if(!$this->validateAttachmentsSize($request->files->get('customFields')) || !$this->validateAttachmentsSize($request->files->get('attachments'))) {
  59.             $errorMain true;
  60.             $errorFlashMessage =  $this->translator->trans("Warning ! Files size can not exceed %size% MB", [
  61.                                         "%size%" => $this->customContainer->getParameter('max_upload_size')
  62.                                     ]);
  63.         } elseif($companyCustomFields $this->getCustomFieldsArray($userType)) {
  64.             foreach ($companyCustomFields as $customField) {
  65.                 if('file' == $customField['fieldType']) {
  66.                     $fileCf $request->files->get('customFields');
  67.                     $customFieldValue = isset($fileCf[$customField['id']]) ? $fileCf[$customField['id']] : null;
  68.                 } else {
  69.                     $customFieldValue = isset($data['customFields'][$customField['id']]) ? $data['customFields'][$customField['id']] : null;
  70.                 }
  71.                 $customField['validation']['required'] = $customField['required'];
  72.                 $customField['validation']['fieldtype'] = $customField['fieldType'] ? : $customField['validation']['fieldtype'] ;
  73.                 if(count($customField['customFieldsDependency'])) {
  74.                     $ticketType $this->entityManager->getRepository(TicketType::class)->findOneById(isset($data['type']) ? $data['type'] : '' );
  75.                     if($ticketType) {
  76.                         $typeId $ticketType->getId();
  77.                         $flag 0;
  78.                         foreach($customField['customFieldsDependency'] as $dependency) {
  79.                             if($dependency['id'] == $typeId) {
  80.                                 $flag 1; break;
  81.                             }
  82.                         }
  83.                     }
  84.                     if(empty($flag)) {
  85.                         continue;
  86.                     }
  87.                 } elseif(in_array($customField['fieldType'], ['checkbox''radio''select']) && empty($customField['customFieldValues'])) {
  88.                     continue;
  89.                 }
  90.                 $errorMessage $this->validationService->messageValidate($customField['validation'], $customFieldValue);
  91.                 if($errorMessage) {
  92.                     $formErrors["customFields[".$customField['id']."]"] = $errorMessage;
  93.                 }
  94.             }
  95.         }
  96.         
  97.         return ['errorMain' => $errorMain'formErrors' => $formErrors'errorFlashMessage' => $errorFlashMessage];
  98.     }
  99.     public function customFieldsValidationWithoutRequired(Request $request$userType 'both')
  100.     {
  101.         $errorMain false;
  102.         $formErrors = [];
  103.         $errorFlashMessage null;
  104.         $data $request->request->all() ? : json_decode($request->getContent(), true);
  105.         if(!$this->validateAttachmentsSize($request->files->get('customFields')) || !$this->validateAttachmentsSize($request->files->get('attachments'))) {
  106.             $errorMain true;
  107.             $errorFlashMessage =  $this->translator->trans("Warning ! Files size can not exceed %size% MB", [
  108.                                         "%size%" => $this->customContainer->getParameter('max_upload_size')]);                                        
  109.         } elseif($companyCustomFields $this->getCustomFieldsArray($userType)) {
  110.             foreach ($companyCustomFields as $customField) {
  111.                 $customField['validation']['required'] = false;
  112.                 $customField['validation']['fieldtype'] = $customField['fieldType'] ? : $customField['validation']['fieldtype'] ;
  113.                 if('file' == $customField['fieldType']) {
  114.                     $fileCf $request->files->get('customFields');
  115.                     $customFieldValue = isset($fileCf[$customField['id']]) ? $fileCf[$customField['id']] : null;
  116.                 } else {
  117.                     $customFieldValue = isset($data['customFields'][$customField['id']]) ? $data['customFields'][$customField['id']] : null;
  118.                 }
  119.                 if(count($customField['customFieldsDependency'])) {
  120.                     $ticketType $this->entityManager->getRepository(TicketType::class)->findOneById(isset($data['type']) ? $data['type'] : '' );
  121.                     if($ticketType) {
  122.                         $typeId $ticketType->getId();
  123.                         $flag 0;
  124.                         foreach($customField['customFieldsDependency'] as $dependency) {
  125.                             if($dependency['id'] == $typeId) {
  126.                                 $flag 1; break;
  127.                             }
  128.                         }
  129.                     }
  130.                     if(empty($flag)) {
  131.                         continue;
  132.                     }
  133.                 } elseif(in_array($customField['fieldType'], ['checkbox''radio''select']) && empty($customField['customFieldValues'])) {
  134.                     continue;
  135.                 }
  136.                 $errorMessage $this->validationService->messageValidate($customField['validation'],  $customFieldValue);
  137.                 if($errorMessage) {
  138.                     $formErrors["customFields[".$customField['id']."]"] = $errorMessage;
  139.                 }
  140.             }
  141.         }
  142.         return ['errorMain' => $errorMain'formErrors' => $formErrors'errorFlashMessage' => $errorFlashMessage];
  143.     }
  144.     /**
  145.     * customFieldValidation for some field
  146.     *
  147.     * @param Request $request
  148.     * @param Array $customFields , validate against these customFields
  149.     *
  150.     * @return Array with keys: 'errorMain', 'formErrors', 'errorFlashMessage'
  151.     */
  152.     public function partialCustomFieldsValidation(Request $request, Array $customFields$prefix '')
  153.     {
  154.         $errorMain false;
  155.         $formErrors = [];
  156.         $errorFlashMessage null;
  157.         $data $request->request->all() ? : json_decode($request->getContent(), true);
  158.         if(!$this->validateAttachmentsSize($request->files->get('customFields')) || !$this->validateAttachmentsSize($request->files->get('attachments'))) {
  159.             $errorMain true;
  160.             $errorFlashMessage =  $this->translator->trans("Warning ! Files size can not exceed %size% MB", [
  161.                                         "%size%" => $this->customContainer->getParameter('max_upload_size')]);
  162.         } else {
  163.             foreach ($customFields as $customField) {
  164.                 if('file' == $customField['fieldType']) {
  165.                     $fileCf $request->files->get('customFields');
  166.                     $customFieldValue = isset($fileCf[$customField['id']]) ? $fileCf[$customField['id']] : null;
  167.                 } else {
  168.                     $customFieldValue = isset($data['customFields'][$customField['id']]) ? $data['customFields'][$customField['id']] : null;
  169.                 }
  170.                 $customField['validation']['required'] = $customField['required'];
  171.                 $customField['validation']['fieldtype'] = $customField['fieldType'] ? : $customField['validation']['fieldtype'];
  172.                 if(count($customField['customFieldsDependency'])) {
  173.                     $ticketType $this->entityManager->getRepository(TicketType::class)->findOneById(isset($data['type']) ? $data['type'] : '' );
  174.                     if($ticketType) {
  175.                         $typeId $ticketType->getId();
  176.                         $flag 0;
  177.                         foreach($customField['customFieldsDependency'] as $dependency) {
  178.                             if($dependency['id'] == $typeId) {
  179.                                 $flag 1; break;
  180.                             }
  181.                         }
  182.                     }
  183.                     if(empty($flag)) {
  184.                         continue;
  185.                     }
  186.                 } elseif(in_array($customField['fieldType'], ['checkbox''radio''select']) && empty($customField['customFieldValues'])) {
  187.                     continue;
  188.                 }
  189.                 $errorMessage $this->validationService->messageValidate($customField['validation'],  $customFieldValue);
  190.                 if($errorMessage) {
  191.                     $formErrors["customFields[".$customField['id']."]"] = $errorMessage;
  192.                 }
  193.             }
  194.         }
  195.         return ['errorMain' => $errorMain'formErrors' => $formErrors'errorFlashMessage' => $errorFlashMessage];
  196.     }
  197.     public function partialCustomFieldsValidationBinaka(Request $request, Array $customFields$prefix '')
  198.     {
  199.         $errorMain false;
  200.         $formErrors = [];
  201.         $errorFlashMessage null;
  202.         $data $request->request->all() ? : json_decode($request->getContent(), true);
  203.         if(!$this->validateAttachmentsSize($request->files->get('customFields')) || !$this->validateAttachmentsSize($request->files->get('attachments'))) {
  204.             $errorMain true;
  205.             $errorFlashMessage =  $this->translator->trans("Warning ! Files size can not exceed %size% MB", [
  206.                                         "%size%" => $this->customContainer->getParameter('max_upload_size')
  207.                                     ]);
  208.         } else {
  209.             foreach ($customFields as $customField) {
  210.                 if(isset($customField['attr']['required']))
  211.                     $customField['validation']['required'] = $customField['attr']['required'];
  212.                 else
  213.                     $customField['validation']['required'] = false;
  214.                 
  215.                 if (!empty($customField['attr']['type']) && 'file' == $customField['attr']['type']) {
  216.                     $fileCf $request->files->get('customFields');
  217.                     $customFieldValue = isset($fileCf[$customField['id']]) ? $fileCf[$customField['id']] : null;
  218.                 } else {
  219.                     $customFieldValue = isset($data['customFields'][$customField['id']]) ? $data['customFields'][$customField['id']] : null;
  220.                 }
  221.                 if(count($customField['dependency'])) {
  222.                     $ticketType $this->entityManager->getRepository(TicketType::class)->findOneById(isset($data['type']) ? $data['type'] : '' );
  223.                     if($ticketType) {
  224.                         $typeId $ticketType->getId();
  225.                         $flag 0;
  226.                         foreach($customField['dependency'] as $dependency) {
  227.                             if($dependency['id'] == $typeId) {
  228.                                 $flag 1; break;
  229.                             }
  230.                         }
  231.                     }
  232.                     if(empty($flag)) {
  233.                         continue;
  234.                     }
  235.                 } elseif(isset($customField['fieldType']) && in_array($customField['fieldType'], ['checkbox''radio''select']) && empty($customField['customFieldValues'])) {
  236.                     continue;
  237.                 }
  238.                 $errorMessage $validationService->messageValidate($customField['validation'],  $customFieldValue);
  239.                 if($errorMessage) {
  240.                     $formErrors["customFields[".$customField['id']."]"] = $errorMessage;
  241.                 }
  242.             }
  243.         }
  244.         return ['errorMain' => $errorMain'formErrors' => $formErrors'errorFlashMessage' => $errorFlashMessage];
  245.     }
  246.     /**
  247.     * finds active custom fields by company and userType(agentType) , (included customFields for agentType:both)
  248.     *
  249.     * @param string $agentType
  250.     */
  251.     public function getCustomFieldsArray($agentType)
  252.     {
  253.         if('string' !== gettype($agentType)) {
  254.             throw new \Exception('getCustomFieldsArray() expects parameter 1 to be string.');
  255.         }
  256.         $qb $this->entityManager->createQueryBuilder()
  257.                     ->from(CustomFields::class, 'c')
  258.                     ->leftJoin("c.customFieldsDependency",'cfd')
  259.                     ->select('c,cfv,cfd')
  260.                     ->leftJoin("c.customFieldValues",'cfv')
  261.                     ->andWhere('c.status = 1')
  262.                     ->orderBy('c.sortOrder');
  263.         if($agentType && 'both' != $agentType) {
  264.                 $qb->andWhere('c.agentType = :both or c.agentType = :agentType')
  265.                 ->setParameter('agentType',$agentType)
  266.                 ->setParameter('both''both');
  267.         }
  268.         $results =  $qb->getQuery()->getArrayResult();
  269.         foreach ($results as $key => $result) {
  270.             $results[$key]['validation'] = ($result['validation']) ? json_decode($result['validation'],true) : $result['validation'];
  271.         }
  272.         return $results;
  273.     }
  274.     /**
  275.     * get customFields from db using customField Ids
  276.     *
  277.     * @param Array $array (customFieldIds array)
  278.     * @param String $resultType ('array' for array Result, 'object' for object result)
  279.     *
  280.     * @return Array customFieldsCollection with Array/object results
  281.     */
  282.     public function getCustomFieldsByIds(Array $array$resultType 'array')
  283.     {
  284.         if(!in_array($resultType, ['array''object'])) {
  285.             throw new \Exception('getCustomFieldsByIds() expects parameter 3 to be either "array" or "object".');
  286.         }
  287.         $queryBuilder $this->entityManager->createQueryBuilder()
  288.                             ->from(CustomFields::class, 's')
  289.                             ->leftJoin("s.customFieldValues",'cfv')
  290.                             ->leftJoin('s.customFieldsDependency','cfd')
  291.                             ->select('s, cfv, cfd')
  292.                             ->andWhere('s.status= 1')
  293.                             ->andWhere('s.id in (:array)')
  294.                             ->orderBy(
  295.                                     's.sortOrder'
  296.                                 )
  297.                              ->setParameters(
  298.                                 array(
  299.                                         'array' => $array,
  300.                                     )
  301.                                 )
  302.                               ->getQuery()
  303.                             ;
  304.         if($resultType == 'array') {
  305.             $results $queryBuilder->getArrayResult();
  306.             foreach ($results as $key => $result) {
  307.                 $results[$key]['validation'] = ($result['validation']) ? json_decode($result['validation'],true) : $result['validation'];
  308.             }
  309.         } else {
  310.             $results $queryBuilder->getResult();
  311.         }
  312.         return $results;
  313.     }
  314.     private function validateAttachmentsSize($attachments)
  315.     {
  316.         $filesize 0;
  317.         if($attachments) {
  318.             foreach ($attachments as $attachment) {
  319.                 if(is_array($attachment)){
  320.                     foreach ($attachment as $attach) {
  321.                         if($attach)
  322.                             $filesize += $attach->getSize() / 1048576;
  323.                     }
  324.                 }elseif($attachment)
  325.                     $filesize += $attachment->getSize() / 1048576;
  326.             }
  327.         }
  328.         return $filesize $this->customContainer->getParameter('max_upload_size') ? false true;
  329.     }
  330.     public function addFilesEntryToAttachmentTable($fileNames$thread null)
  331.     {
  332.         $newFilesNames = [];
  333.         foreach ($fileNames as $file) {
  334.             $attachment = new Attachment();
  335.             $attachment
  336.                 ->setName($file['name'])
  337.                 ->setPath($file['path'])
  338.                 ->setContentType($file['content-type'])
  339.                 ->setSize($file['size'])
  340.             ;
  341.             if (isset($file['contentId'])) {
  342.                 $attachment
  343.                     ->setContentId($file['contentId'])
  344.                 ;
  345.             }
  346.             if (!empty($thread)) {
  347.                 $attachment
  348.                     ->setThread($thread)
  349.                 ;
  350.             }
  351.             
  352.             $this->entityManager->persist($attachment);
  353.             $this->entityManager->flush();
  354.             $newFilesNames[] =  [
  355.                 'id' => $attachment->getId(),
  356.                 'name' => $attachment->getName(),
  357.                 'path' => $attachment->getPath(),
  358.             ];
  359.         }
  360.         return $newFilesNames;
  361.     }
  362.     
  363.     public function getTicketCustomFieldDetailsCollection(array $ticketReferenceIds)
  364.     {
  365.         $ticketReferences array_map(function ($ticketId) {
  366.             return "ticketCustomField.ticket = $ticketId";
  367.         }, $ticketReferenceIds);
  368.         $ticketReferencesQueryCondition implode(" OR "$ticketReferences);
  369.         $queryBuilder $this->entityManager->createQueryBuilder();
  370.         $ticketCustomFieldDetailsCollection $queryBuilder
  371.             ->select("ticketCustomField")
  372.             ->from(TicketCustomFieldsValues::class, "ticketCustomField")
  373.             ->where($ticketReferencesQueryCondition)
  374.             ->getQuery()
  375.             ->getResult()
  376.         ;
  377.         if (empty($ticketCustomFieldDetailsCollection)) {
  378.             return [];
  379.         }
  380.         $resolvedTicketCustomFieldDetailsCollection = [];
  381.         foreach ($ticketCustomFieldDetailsCollection as $ticketCustomFieldDetails) {
  382.             $customField $ticketCustomFieldDetails->getTicketCustomFieldsValues();
  383.             $customFieldDependencies $customField->getCustomFieldsDependency()->getValues();
  384.             $customFieldValidationRules json_decode($customField->getValidation(), true);
  385.             $resolvedCustomFieldDependencies array_map(function ($ticketType) {
  386.                 return [
  387.                     'id' => $ticketType->getId(), 
  388.                     'code' => $ticketType->getCode(), 
  389.                     'description' => $ticketType->getDescription(), 
  390.                     'isActive' => $ticketType->getIsActive(), 
  391.                 ];
  392.             }, $customFieldDependencies);
  393.             $resolvedCustomFieldValidationRules = [];
  394.             foreach ($customFieldValidationRules as $validationRule => $validationCriteria) {
  395.                 if (!empty($validationCriteria)) {
  396.                     $resolvedCustomFieldValidationRules[$validationRule] = $validationCriteria;
  397.                 }
  398.             }
  399.             // Resolve custom field options
  400.             $customFieldOptions array_map(function ($customFieldOption) {
  401.                 return [
  402.                     "id" => $customFieldOption->getId(), 
  403.                     "name" => $customFieldOption->getName(), 
  404.                 ];
  405.             }, $customField->getCustomFieldValues());
  406.             $customFieldDetails = [
  407.                 'id' => $customField->getId(), 
  408.                 'name' => $customField->getName(), 
  409.                 'type' => $customField->getFieldType(), 
  410.                 'placeholder' => $customField->getPlaceholder(), 
  411.                 'isRequired' => $customField->getRequired(), 
  412.                 'isEncrypted' => $customField->getEncryption(), 
  413.                 'status' => $customField->getStatus(), 
  414.                 'sortOrder' => $customField->getSortOrder(), 
  415.                 'createdAt' => $this->userService->convertDateTimeToSupportedUserTimeFormat($customField->getDateAdded()), 
  416.                 'lastUpdatedAt' => $this->userService->convertDateTimeToSupportedUserTimeFormat($customField->getDateUpdated()), 
  417.                 'options' => $customFieldOptions
  418.                 'dependencies' => $resolvedCustomFieldDependencies
  419.                 'validations' => $resolvedCustomFieldValidationRules
  420.             ];
  421.             $customFieldId $customField->getId();
  422.             $ticketCustomFieldValue $ticketCustomFieldDetails->getValue();
  423.             $resolvedCustomFieldValue null;
  424.             $resolvedCustomFieldValueId null;
  425.             switch ($customField->getFieldType()) {
  426.                 case 'select':
  427.                 case 'radio':
  428.                 case 'checkbox':
  429.                     $fieldId = [];
  430.                     $fieldValue = [];
  431.                     if ($ticketCustomFieldDetails->getEncrypted()) {
  432.                         $ticketCustomFieldDetails->decryptEntity();
  433.                     }
  434.                     $fieldOptions json_decode($ticketCustomFieldValuetrue);
  435.                     if (empty($fieldOptions)) {
  436.                         $fieldOptions explode(','$ticketCustomFieldValue);
  437.                     } else {
  438.                         if (!is_array($fieldOptions)) {
  439.                             $fieldOptions = [$fieldOptions];
  440.                         }
  441.                     }
  442.                     foreach ($customField->getCustomFieldValues() as $multipleFieldValue) {
  443.                         if (in_array($multipleFieldValue->getId(), $fieldOptions)) {
  444.                             $fieldId[] = $multipleFieldValue->getId();
  445.                             $fieldValue[] = $multipleFieldValue->getName();
  446.                         }
  447.                     }
  448.                     $resolvedCustomFieldValue $ticketCustomFieldDetails->getEncrypted() ? nullimplode('</br>'$fieldValue);
  449.                     $resolvedCustomFieldValueId $fieldId;
  450.                     break;
  451.                 case 'file':
  452.                     $resolvedCustomFieldValue $ticketCustomFieldDetails->getEncrypted() ? null strip_tags(trim($ticketCustomFieldValue'"'));
  453.                     try {
  454.                         if (!empty($resolvedCustomFieldValue)) {
  455.                             $resolvedCustomFieldValue json_decode($resolvedCustomFieldValuetrue);
  456.                         }
  457.                     } catch (\Exception $e) {
  458.                         // Do nothing...
  459.                     }
  460.                     break;
  461.                 default:
  462.                     if (false == $ticketCustomFieldDetails->getEncrypted()) {
  463.                         if (is_array(trim($ticketCustomFieldValue'"'))) {
  464.                             $resolvedCustomFieldValue json_encode(trim($ticketCustomFieldValue'"'));
  465.                         } else {
  466.                             $resolvedCustomFieldValue strip_tags(htmlentities(trim($ticketCustomFieldValue'"')));
  467.                         }
  468.                     } else {
  469.                         $resolvedCustomFieldValue null;
  470.                     }
  471.                     break;
  472.             }
  473.             $resolvedTicketCustomFieldDetailsCollection[] = [
  474.                 'id' => $ticketCustomFieldDetails->getId(), 
  475.                 'value' => $resolvedCustomFieldValue
  476.                 'valueId' => $resolvedCustomFieldValueId
  477.                 'ticketId' => $ticketCustomFieldDetails->getTicket()->getId(), 
  478.                 'isEncrypted' => $ticketCustomFieldDetails->getEncrypted() ? true false
  479.                 'customField' => $customFieldDetails
  480.             ];
  481.         }
  482.         $ticketCustomFieldDetailsCollectionGroupedByTicket = [];
  483.         foreach ($resolvedTicketCustomFieldDetailsCollection as $ticketCustomFieldDetails) {
  484.             $ticketCustomFieldDetailsCollectionGroupedByTicket[$ticketCustomFieldDetails['ticketId']][] = $ticketCustomFieldDetails;
  485.         }
  486.         return $ticketCustomFieldDetailsCollectionGroupedByTicket;
  487.     }
  488.     public function getTicketCustomFieldDetails($ticketId)
  489.     {
  490.         $collection $this->entityManager->getRepository(TicketCustomFieldsValues::class)->findBy(['ticket' => $ticketId]);
  491.         if (empty($collection)) {
  492.             return [];
  493.         }
  494.         $_collection = [];
  495.         foreach ($collection as $ticketCustomFieldDetails) {
  496.             $customField $ticketCustomFieldDetails->getTicketCustomFieldsValues();
  497.             $customFieldDependencies $customField->getCustomFieldsDependency()->getValues();
  498.             $customFieldValidationRules json_decode($customField->getValidation(), true);
  499.             $resolvedCustomFieldDependencies array_map(function ($ticketType) {
  500.                 return [
  501.                     'id' => $ticketType->getId(), 
  502.                     'code' => $ticketType->getCode(), 
  503.                     'description' => $ticketType->getDescription(), 
  504.                     'isActive' => $ticketType->getIsActive(), 
  505.                 ];
  506.             }, $customFieldDependencies);
  507.             $resolvedCustomFieldValidationRules = [];
  508.             foreach ($customFieldValidationRules as $validationRule => $validationCriteria) {
  509.                 if (!empty($validationCriteria)) {
  510.                     $resolvedCustomFieldValidationRules[$validationRule] = $validationCriteria;
  511.                 }
  512.             }
  513.             // Resolve custom field options
  514.             $customFieldOptions array_map(function ($customFieldOption) {
  515.                 return [
  516.                     "id" => $customFieldOption->getId(), 
  517.                     "name" => $customFieldOption->getName(), 
  518.                 ];
  519.             }, $customField->getCustomFieldValues());
  520.             $customFieldDetails = [
  521.                 'id' => $customField->getId(), 
  522.                 'name' => $customField->getName(), 
  523.                 'type' => $customField->getFieldType(), 
  524.                 'placeholder' => $customField->getPlaceholder(), 
  525.                 'isRequired' => $customField->getRequired(), 
  526.                 'isEncrypted' => $customField->getEncryption(), 
  527.                 'status' => $customField->getStatus(), 
  528.                 'sortOrder' => $customField->getSortOrder(), 
  529.                 'createdAt' => $this->userService->convertDateTimeToSupportedUserTimeFormat($customField->getDateAdded()), 
  530.                 'lastUpdatedAt' => $this->userService->convertDateTimeToSupportedUserTimeFormat($customField->getDateUpdated()), 
  531.                 'options' => $customFieldOptions
  532.                 'dependencies' => $resolvedCustomFieldDependencies
  533.                 // 'agentType' => $customField->getAgentType(), 
  534.                 'validations' => $resolvedCustomFieldValidationRules
  535.             ];
  536.             $customFieldId $customField->getId();
  537.             $ticketCustomFieldValue $ticketCustomFieldDetails->getValue();
  538.             $resolvedCustomFieldValue null;
  539.             $resolvedCustomFieldValueId null;
  540.             switch ($customField->getFieldType()) {
  541.                 case 'select':
  542.                 case 'radio':
  543.                 case 'checkbox':
  544.                     $fieldId = [];
  545.                     $fieldValue = [];
  546.                     if ($ticketCustomFieldDetails->getEncrypted()) {
  547.                         $ticketCustomFieldDetails->decryptEntity();
  548.                     }
  549.                     $fieldOptions json_decode($ticketCustomFieldValuetrue);
  550.                     if (empty($fieldOptions)) {
  551.                         $fieldOptions explode(','$ticketCustomFieldValue);
  552.                     } else {
  553.                         if (!is_array($fieldOptions)) {
  554.                             $fieldOptions = [$fieldOptions];
  555.                         }
  556.                     }
  557.                     foreach ($customField->getCustomFieldValues() as $multipleFieldValue) {
  558.                         if (in_array($multipleFieldValue->getId(), $fieldOptions)) {
  559.                             $fieldId[] = $multipleFieldValue->getId();
  560.                             $fieldValue[] = $multipleFieldValue->getName();
  561.                         }
  562.                     }
  563.                     $resolvedCustomFieldValue $ticketCustomFieldDetails->getEncrypted() ? nullimplode('</br>'$fieldValue);
  564.                     $resolvedCustomFieldValueId $fieldId;
  565.                     break;
  566.                 case 'file':
  567.                     $resolvedCustomFieldValue $ticketCustomFieldDetails->getEncrypted() ? null strip_tags(trim($ticketCustomFieldValue'"'));
  568.                     try {
  569.                         if (!empty($resolvedCustomFieldValue)) {
  570.                             $resolvedCustomFieldValue json_decode($resolvedCustomFieldValuetrue);
  571.                         }
  572.                     } catch (\Exception $e) {
  573.                         // Do nothing...
  574.                     }
  575.                     break;
  576.                 default:
  577.                     if (false == $ticketCustomFieldDetails->getEncrypted()) {
  578.                         if (is_array(trim($ticketCustomFieldValue'"'))) {
  579.                             $resolvedCustomFieldValue json_encode(trim($ticketCustomFieldValue'"'));
  580.                         } else {
  581.                             $resolvedCustomFieldValue strip_tags(htmlentities(trim($ticketCustomFieldValue'"')));
  582.                         }
  583.                     } else {
  584.                         $resolvedCustomFieldValue null;
  585.                     }
  586.                     break;
  587.             }
  588.             $_collection[] = [
  589.                 'id' => $ticketCustomFieldDetails->getId(), 
  590.                 'value' => $resolvedCustomFieldValue
  591.                 'valueId' => $resolvedCustomFieldValueId
  592.                 'isEncrypted' => $ticketCustomFieldDetails->getEncrypted() ? true false
  593.                 'customField' => $customFieldDetails
  594.             ];
  595.         }
  596.         return $_collection;
  597.     }
  598.     /**
  599.     * returns custom field snippet containing html, js for ticket view
  600.     */
  601.     public function getCustomFieldSnippet(Ticket $ticket): array
  602.     {
  603.         $customFieldCollection $this->getCustomFieldsArray('both');
  604.         
  605.         if (!empty($customFieldCollection)) {
  606.             $ticketCustomFieldArrayCollection = [];
  607.             $ticketCustomFieldCollection $this->entityManager->getRepository(TicketCustomFieldsValues::class)->findBy(['ticket' => $ticket]);
  608.             if (!empty($ticketCustomFieldCollection)) {
  609.                 foreach ($ticketCustomFieldCollection as $ticketCustomField) {
  610.                     $ticketCustomFieldArrayCollection[$ticketCustomField->getTicketCustomFieldsValues()->getId()] = [
  611.                         'id' => $ticketCustomField->getId(),
  612.                         'encrypted' => $ticketCustomField->getEncrypted() ? true false,
  613.                         'targetCustomField' => $ticketCustomField->getTicketCustomFieldsValues()->getId(),
  614.                     ];
  615.                     switch ($ticketCustomField->getTicketCustomFieldsValues()->getFieldType()) {
  616.                         case 'select':
  617.                         case 'radio':
  618.                         case 'checkbox':
  619.                             $fieldId = [];
  620.                             $fieldValue = [];
  621.                             if ($ticketCustomField->getEncrypted()) {
  622.                                 $ticketCustomField->decryptEntity();
  623.                             }
  624.                             $fieldOptions json_decode($ticketCustomField->getValue(), true);
  625.                             if (empty($fieldOptions)) {
  626.                                 $fieldOptions explode(','$ticketCustomField->getValue());
  627.                             } else {
  628.                                 if (!is_array($fieldOptions)) {
  629.                                     $fieldOptions = [$fieldOptions];
  630.                                 }
  631.                             }
  632.                             foreach ($ticketCustomField->getTicketCustomFieldsValues()->getCustomFieldValues() as $multipleFieldValue) {
  633.                                 if (in_array($multipleFieldValue->getId(), $fieldOptions)) {
  634.                                     $fieldId[] = $multipleFieldValue->getId();
  635.                                     $fieldValue[] = $multipleFieldValue->getName();
  636.                                 }
  637.                             }
  638.                             $ticketCustomFieldArrayCollection[$ticketCustomField->getTicketCustomFieldsValues()->getId()]['valueId'] = $fieldId;
  639.                             $ticketCustomFieldArrayCollection[$ticketCustomField->getTicketCustomFieldsValues()->getId()]['value'] = $ticketCustomField->getEncrypted() ? nullimplode('</br>'$fieldValue);
  640.                             break;
  641.                         case 'file':
  642.                             $ticketCustomFieldArrayCollection[$ticketCustomField->getTicketCustomFieldsValues()->getId()]['value'] = $ticketCustomField->getEncrypted() ? null strip_tags(trim($ticketCustomField->getValue(), '"'));
  643.                             break;
  644.                         default:
  645.                             $ticketCustomFieldArrayCollection[$ticketCustomField->getTicketCustomFieldsValues()->getId()]['value'] = (!$ticketCustomField->getEncrypted()
  646.                                 ? (is_array(trim($ticketCustomField->getValue(), '"'))
  647.                                     ? json_encode(trim($ticketCustomField->getValue(), '"'))
  648.                                     : strip_tags(htmlentities(trim($ticketCustomField->getValue(), '"')))
  649.                                 )
  650.                                 : null
  651.                             );
  652.                             break;
  653.                     }
  654.                 }
  655.             }
  656.             return [
  657.                 'ticket' => $ticket,
  658.                 'customFieldCollection' => $customFieldCollection,
  659.                 'ticketCustomFieldCollection' => $ticketCustomFieldArrayCollection
  660.             ];
  661.         }
  662.         return [
  663.             'ticket' => $ticket,
  664.             'customFieldCollection' => [],
  665.             'ticketCustomFieldCollection' => []
  666.         ];
  667.     }
  668.     public function getCustomerCustomFieldSnippet($ticket): array
  669.     {   
  670.         $customFieldCollection $this->getCustomFieldsArray('customer');
  671.         $ticketCustomFieldArrayCollection = [];
  672.         $ticketCustomFieldCollection $this->entityManager->getRepository(TicketCustomFieldsValues::class)->findBy(['ticket' => $ticket]);
  673.         /* load custom fields whose value is already present in ticket */ 
  674.         $existingCfIds array_column($customFieldCollection'id');
  675.         $cfIds = [];
  676.         foreach($ticketCustomFieldCollection as $cfValue) {
  677.             $id $cfValue->getTicketCustomFieldsValues()->getId();
  678.             if($cfValue->getTicketCustomFieldsValues()->getStatus() && !in_array($id$existingCfIds)) {
  679.                 $cfIds[] = $id;
  680.             }
  681.         }
  682.         $ticketCfs $this->getCustomFieldsByIds($cfIds);
  683.         $customFieldCollection array_merge($customFieldCollection$ticketCfs);
  684.         /* format data */ 
  685.         if (!empty($customFieldCollection)) {
  686.             foreach ($ticketCustomFieldCollection as $ticketCustomField) {
  687.                 $ticketCustomFieldArrayCollection[$ticketCustomField->getTicketCustomFieldsValues()->getId()] = [
  688.                     'id' => $ticketCustomField->getId(),
  689.                     'encrypted' => $ticketCustomField->getEncrypted() ? true false,
  690.                     'targetCustomField' => $ticketCustomField->getTicketCustomFieldsValues()->getId(),
  691.                     'targetCustomFieldName' => $ticketCustomField->getTicketCustomFieldsValues()->getId(),
  692.                 ];
  693.                 switch ($ticketCustomField->getTicketCustomFieldsValues()->getFieldType()) {
  694.                     case 'select':
  695.                     case 'radio':
  696.                     case 'checkbox':
  697.                         $fieldId = [];
  698.                         $fieldValue = [];
  699.                         if ($ticketCustomField->getEncrypted()) {
  700.                             $ticketCustomField->decryptEntity();
  701.                         }
  702.                         $fieldOptions json_decode($ticketCustomField->getValue(), true);
  703.                         if (empty($fieldOptions)) {
  704.                             $fieldOptions explode(','$ticketCustomField->getValue());
  705.                         } else {
  706.                             if (!is_array($fieldOptions)) {
  707.                                 $fieldOptions = [$fieldOptions];
  708.                             }
  709.                         }
  710.                         foreach ($ticketCustomField->getTicketCustomFieldsValues()->getCustomFieldValues() as $multipleFieldValue) {
  711.                             if (in_array($multipleFieldValue->getId(), $fieldOptions)) {
  712.                                 $fieldId[] = $multipleFieldValue->getId();
  713.                                 $fieldValue[] = $multipleFieldValue->getName();
  714.                             }
  715.                         }
  716.                         $ticketCustomFieldArrayCollection[$ticketCustomField->getTicketCustomFieldsValues()->getId()]['valueId'] = $fieldId;
  717.                         $ticketCustomFieldArrayCollection[$ticketCustomField->getTicketCustomFieldsValues()->getId()]['value'] = $ticketCustomField->getEncrypted() ? nullimplode('</br>'$fieldValue);
  718.                         break;
  719.                     default:
  720.                         $ticketCustomFieldArrayCollection[$ticketCustomField->getTicketCustomFieldsValues()->getId()]['value'] = (!$ticketCustomField->getEncrypted()
  721.                             ? (is_array(trim($ticketCustomField->getValue(), '"'))
  722.                                 ? json_encode(trim($ticketCustomField->getValue(), '"'))
  723.                                 : strip_tags(htmlentities(trim($ticketCustomField->getValue(), '"')))
  724.                             )
  725.                             : null
  726.                         );
  727.                         break;
  728.                 }
  729.             }
  730.             
  731.             return ['ticket' => $ticket,
  732.                 'customFieldCollection' => $customFieldCollection,
  733.                 'ticketCustomFieldCollection' => $ticketCustomFieldArrayCollection
  734.             ];
  735.         }
  736.         return [
  737.             'ticket' => $ticket,
  738.             'customFieldCollection' => [],
  739.             'ticketCustomFieldCollection' => []
  740.         ];
  741.     }
  742.     private function getAvailableCustomFieldsCollection($agentType)
  743.     {
  744.         $queryBuilder $this->entityManager->createQueryBuilder()
  745.             ->from(CustomFields::class, 'c')
  746.             ->leftJoin("c.customFieldsDependency"'cfd')
  747.             ->select('c, cfv, cfd')
  748.             ->leftJoin("c.customFieldValues"'cfv')
  749.             ->andWhere('c.status = 1')
  750.             ->orderBy('c.sortOrder')
  751.         ;
  752.         if ($agentType && 'both' != $agentType) {
  753.             $queryBuilder
  754.                 ->andWhere('c.agentType = :both or c.agentType = :agentType')
  755.                 ->setParameter('agentType'$agentType)
  756.                 ->setParameter('both''both')
  757.             ;
  758.         }
  759.         $collection $queryBuilder->getQuery()->getArrayResult();
  760.         foreach ($collection as $index => $customField) {
  761.             $collection[$index]['validation'] = !empty($customField['validation']) ? json_decode($customField['validation'], true) : $customField['validation'];
  762.         }
  763.         return $collection;
  764.     }
  765.     public function validateCustomFieldsWithoutRequired($ticket$customField$params$uploadedFiles$userType 'both')
  766.     {
  767.         $customFieldValue null;
  768.         
  769.         if ('file' == $customField->getFieldType()) {
  770.             if (!empty($uploadedFiles['ticketCustomFieldValue'])) {
  771.                 if (!$this->validateAttachmentsSize($uploadedFiles['ticketCustomFieldValue'])) {
  772.                     return [false"File size can not exceed {$this->customContainer->getParameter('max_upload_size')} MB"];
  773.                 }
  774.                 $customFieldValue $uploadedFiles['ticketCustomFieldValue'];
  775.             }
  776.         } else {
  777.             if (!isset($params['customFieldValue'])) {
  778.                 return [false"No custom field value was provided."];
  779.             }
  780.             $customFieldValue $params['customFieldValue'];
  781.         }
  782.         $customFieldTicketTypeDependencies $customField->getCustomFieldsDependency()->getValues();
  783.         if (!empty($customFieldTicketTypeDependencies)) {
  784.             $isTicketTypeSupported false;
  785.             $ticketType $ticket->getType();
  786.             foreach ($customFieldTicketTypeDependencies as $supportedTicketType) {
  787.                 if ($ticketType->getId() == $supportedTicketType->getId()) {
  788.                     $isTicketTypeSupported true;
  789.                     break;
  790.                 }
  791.             }
  792.             if (false == $isTicketTypeSupported) {
  793.                 return [false"Custom field is not applicable on ticket of type '{$ticketType->getDescription()}'."];
  794.             }
  795.         }
  796.         $validationRules json_decode($customField->getValidation() ?: self::DEFAULT_VALIDATION_RULEStrue);
  797.         $validationErrorMessage $this->validationService->messageValidate($validationRules,  $customFieldValue);
  798.         if (!empty($validationErrorMessage)) {
  799.             return [false$validationErrorMessage];
  800.         }
  801.         return [truenull];
  802.     }
  803. }