<?php
namespace Webkul\UVDesk\ApiBundle\API;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\Encoder\XmlEncoder;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Webkul\UVDesk\CoreFrameworkBundle\Entity as CoreFrameworkBundleEntity;
use Webkul\UVDesk\CoreFrameworkBundle\Workflow\Events as CoreWorkflowEvents;
use Webkul\UVDesk\CoreFrameworkBundle\Services\UVDeskService;
class Tickets extends AbstractController
{
/**
* Return support tickets.
*
* @param Request $request
*/
public function fetchTickets(Request $request, ContainerInterface $container, UVDeskService $uvdesk, EntityManagerInterface $entityManager)
{
$json = [];
$ticketRepository = $entityManager->getRepository(CoreFrameworkBundleEntity\Ticket::class);
$userRepository = $entityManager->getRepository(CoreFrameworkBundleEntity\User::class);
if ($request->query->get('actAsType')) {
switch ($request->query->get('actAsType')) {
case 'customer':
$email = $request->query->get('actAsEmail');
$customer = $entityManager->getRepository(CoreFrameworkBundleEntity\User::class)->findOneByEmail($email);
if ($customer) {
$json = $ticketRepository->getAllCustomerTickets($request->query, $container, $customer);
} else {
$json['error'] = $container->get('translator')->trans('Error! Resource not found.');
return new JsonResponse($json, Response::HTTP_NOT_FOUND);
}
return new JsonResponse($json);
case 'agent':
$email = $request->query->get('actAsEmail');
$user = $entityManager->getRepository(CoreFrameworkBundleEntity\User::class)->findOneByEmail($email);
if ($user) {
$request->query->set('agent', $user->getId());
} else {
$json['error'] = $container->get('translator')->trans('Error! Resource not found.');
return new JsonResponse($json, Response::HTTP_NOT_FOUND);
}
break;
default:
$json['error'] = $container->get('translator')->trans('Error! invalid actAs details.');
return new JsonResponse($json, Response::HTTP_BAD_REQUEST);
}
}
$json = $ticketRepository->getAllTickets($request->query, $container);
$collection = $json['tickets'];
$pagination = $json['pagination'];
// Resolve asset paths
$defaultAgentProfileImagePath = $this->getParameter('assets_default_agent_profile_image_path');
$defaultCustomerProfileImagePath = $this->getParameter('assets_default_customer_profile_image_path');
$user = $this->getUser();
$userInstance = $user->getCurrentInstance();
$currentUserDetails = [
'id' => $user->getId(),
'email' => $user->getEmail(),
'name' => $user->getFirstName() . ' ' . $user->getLastname(),
'profileImagePath' => $uvdesk->generateCompleteLocalResourcePathUri($userInstance->getProfileImagePath() ?? $defaultAgentProfileImagePath)
];
foreach ($collection as $index => $ticket) {
// Resolve assets: Assigned agent
if (! empty($ticket['agent'])) {
$profileImagePath = $uvdesk->generateCompleteLocalResourcePathUri($ticket['agent']['profileImagePath'] ?? $defaultAgentProfileImagePath);
$smallThumbnailPath = $uvdesk->generateCompleteLocalResourcePathUri($ticket['agent']['smallThumbnail'] ?? $defaultAgentProfileImagePath);
$collection[$index]['agent']['profileImagePath'] = $profileImagePath;
$collection[$index]['agent']['smallThumbnail'] = $smallThumbnailPath;
}
// Resolve assets: Customer
if (! empty($ticket['customer'])) {
$profileImagePath = $uvdesk->generateCompleteLocalResourcePathUri($ticket['customer']['profileImagePath'] ?? $defaultCustomerProfileImagePath);
$smallThumbnailPath = $uvdesk->generateCompleteLocalResourcePathUri($ticket['customer']['smallThumbnail'] ?? $defaultCustomerProfileImagePath);
$collection[$index]['customer']['profileImagePath'] = $profileImagePath;
$collection[$index]['customer']['smallThumbnail'] = $smallThumbnailPath;
}
}
// Available helpdesk agents collection
$agents = $container->get('user.service')->getAgentsPartialDetails();
return new JsonResponse([
'tickets' => $collection,
'pagination' => $pagination,
'userDetails' => $currentUserDetails,
'agents' => $agents,
'status' => $container->get('ticket.service')->getStatus(),
'group' => $userRepository->getSupportGroups(),
'team' => $userRepository->getSupportTeams(),
'priority' => $container->get('ticket.service')->getPriorities(),
'type' => $container->get('ticket.service')->getTypes(),
'source' => $container->get('ticket.service')->getAllSources(),
]);
return new JsonResponse($json);
}
/**
* Trash support tickets.
*
* @param Request $request
* @return void
*/
public function trashTicket(Request $request, ContainerInterface $container, EntityManagerInterface $entityManager)
{
$ticketId = $request->attributes->get('ticketId');
$ticket = $entityManager->getRepository(CoreFrameworkBundleEntity\Ticket::class)->find($ticketId);
if (! $ticket) {
throw new NotFoundHttpException('Ticket Not Found');
}
if (!$ticket->getIsTrashed()) {
$ticket->setIsTrashed(1);
$entityManager->persist($ticket);
$entityManager->flush();
$json['success'] = $container->get('translator')->trans('Success ! Ticket moved to trash successfully.');
$statusCode = Response::HTTP_OK;
// Trigger ticket delete event
$event = new CoreWorkflowEvents\Ticket\Delete();
$event
->setTicket($ticket);
$container->get('event_dispatcher')->dispatch($event, 'uvdesk.automation.workflow.execute');
} else {
$json['error'] = $container->get('translator')->trans('Warning ! Ticket is already in trash.');
$statusCode = Response::HTTP_BAD_REQUEST;
}
return new JsonResponse($json, $statusCode);
}
/**
* Create support tickets.
* customFields data passed like :
* {
* customFields[key] : value,
* customFields[key] : value,
* }
*
* @param Request $request
* @return void
*/
public function createTicket(Request $request, ContainerInterface $container, EntityManagerInterface $entityManager)
{
$data = $request->request->all() ?: json_decode($request->getContent(), true);
foreach ($data as $key => $value) {
if (!in_array($key, ['subject', 'group', 'type', 'status', 'locale', 'domain', 'priority', 'agent', 'replies', 'createdAt', 'updatedAt', 'customFields', 'files', 'from', 'name', 'message', 'tags', 'actAsType', 'actAsEmail'])) {
unset($data[$key]);
}
}
if (
!(isset($data['from'])
&& isset($data['name'])
&& isset($data['subject'])
&& isset($data['message'])
&& isset($data['actAsType'])
|| isset($data['actAsEmail']))
) {
$json['error'] = $container->get('translator')->trans('required fields: name, from, subject, message, actAsType or actAsEmail');
return new JsonResponse($json, Response::HTTP_BAD_REQUEST);
}
if ($data) {
$error = false;
if ($data['subject'] == '') {
$statusCode = Response::HTTP_BAD_REQUEST;
} elseif ($data['message'] == '') {
$json['message'] = $container->get('translator')->trans("Warning! Please complete message field value!");
$statusCode = Response::HTTP_BAD_REQUEST;
} elseif (filter_var($data['from'], FILTER_VALIDATE_EMAIL) === false) {
$json['message'] = $container->get('translator')->trans("Warning! Invalid from Email Address!");
$statusCode = Response::HTTP_BAD_REQUEST;
} elseif ($data['actAsType'] == '' && $data['actAsEmail'] == '') {
$json['message'] = $container->get('translator')->trans("Warning! Provide atleast one parameter actAsType(agent or customer) or actAsEmail");
$statusCode = Response::HTTP_BAD_REQUEST;
}
if (! $error) {
$name = explode(' ', trim($data['name']));
$ticketData['firstName'] = $name[0];
$ticketData['lastName'] = isset($name[1]) ? $name[1] : '';
$ticketData['role'] = 4;
if (
(array_key_exists('actAsType', $data))
&& (strtolower($data['actAsType']) == 'customer')
) {
$actAsType = strtolower(trim($data['actAsType']));
} else if (
(array_key_exists('actAsEmail', $data))
&& (strtolower(trim($data['actAsType'])) == 'agent')
) {
$user = $entityManager->getRepository(CoreFrameworkBundleEntity\User::class)->findOneByEmail(trim($data['actAsEmail']));
if ($user) {
$actAsType = 'agent';
} else {
$json['error'] = $container->get('translator')->trans("Error ! actAsEmail is not valid");
return new JsonResponse($json, Response::HTTP_BAD_REQUEST);
}
} else {
$json['warning'] = $container->get('translator')->trans('Warning ! For Customer specify actAsType as customer and for Agent specify both parameter actASType as agent and actAsEmail as agent email');
$statusCode = Response::HTTP_BAD_REQUEST;
return new JsonResponse($json, $statusCode);
}
// Create customer if account does not exists
$customer = $entityManager->getRepository(CoreFrameworkBundleEntity\User::class)->findOneByEmail($data['from']);
if (
empty($customer)
|| null == $customer->getCustomerInstance()
) {
$role = $entityManager->getRepository(CoreFrameworkBundleEntity\SupportRole::class)->findOneByCode('ROLE_CUSTOMER');
// Create User Instance
$customer = $container->get('user.service')->createUserInstance($data['from'], $data['name'], $role, [
'source' => 'api',
'active' => true
]);
}
if ($actAsType == 'agent') {
$data['user'] = isset($user) && $user ? $user : $container->get('user.service')->getCurrentUser();
} else {
$data['user'] = $customer;
}
$attachments = $request->files->get('attachments');
if (! empty($attachments)) {
$attachments = is_array($attachments) ? $attachments : [$attachments];
}
$ticketData['user'] = $data['user'];
$ticketData['subject'] = trim($data['subject']);
$ticketData['message'] = trim($data['message']);
$ticketData['customer'] = $customer;
$ticketData['source'] = 'api';
$ticketData['threadType'] = 'create';
$ticketData['createdBy'] = $actAsType;
$ticketData['attachments'] = $attachments;
$extraKeys = ['tags', 'group', 'priority', 'status', 'agent', 'createdAt', 'updatedAt'];
if (array_key_exists('type', $data)) {
$ticketType = $entityManager->getRepository(CoreFrameworkBundleEntity\TicketType::class)->findOneByCode($data['type']);
$ticketData['type'] = $ticketType;
}
foreach ($extraKeys as $key) {
if (isset($ticketData[$key])) {
unset($ticketData[$key]);
}
}
$thread = $container->get('ticket.service')->createTicketBase($ticketData);
$customFields = $request->request->get('customFields');
if ($customFields) {
$container->get('ticket.service')->addTicketCustomFields($thread, $customFields, $customFields);
}
// Trigger ticket created event
try {
$event = new CoreWorkflowEvents\Ticket\Create();
$event
->setTicket($thread->getTicket());
$container->get('event_dispatcher')->dispatch($event, 'uvdesk.automation.workflow.execute');
} catch (\Exception $e) {
}
$user = $this->getUser();
$userService = $container->get('user.service');
$json['message'] = $container->get('translator')->trans('Success ! Ticket has been created successfully.');
$json['ticket'] = [
'id' => $thread->getTicket()->getId(),
'status' => $thread->getTicket()->getStatus()->getId(),
'createdAt' => $userService->getLocalizedFormattedTime($thread->getTicket()->getCreatedAt(), $user),
'updatedAt' => $userService->getLocalizedFormattedTime($thread->getTicket()->getUpdatedAt(), $user),
];
$statusCode = Response::HTTP_OK;
} else {
$json['message'] = $container->get('translator')->trans('Warning ! Required parameters should not be blank');
$statusCode = Response::HTTP_BAD_REQUEST;
}
} else {
$json['error'] = $container->get('translator')->trans('invalid/empty size of Request');
$json['message'] = $container->get('translator')->trans('Warning ! Post size can not exceed 25MB');
$statusCode = Response::HTTP_BAD_REQUEST;
}
return new JsonResponse($json, $statusCode);
}
/**
* View support tickets.
*
* @param Request $request
* @return void
*/
public function viewTicket($ticketId, ContainerInterface $container, UVDeskService $uvdesk, EntityManagerInterface $entityManager)
{
$userRepository = $entityManager->getRepository(CoreFrameworkBundleEntity\User::class);
$ticketRepository = $entityManager->getRepository(CoreFrameworkBundleEntity\Ticket::class);
$ticket = $ticketRepository->findOneById($ticketId);
if (empty($ticket)) {
throw new \Exception('No ticket found');
}
$user = $this->getUser();
$agent = $ticket->getAgent();
$customer = $ticket->getCustomer();
$defaultAgentProfileImagePath = $this->getParameter('assets_default_agent_profile_image_path');
$defaultCustomerProfileImagePath = $this->getParameter('assets_default_customer_profile_image_path');
$agentDetails = !empty($agent) ? $agent->getAgentInstance()->getPartialDetails() : null;
$customerDetails = $customer->getCustomerInstance()->getPartialDetails();
if (! empty($agentDetails)) {
$agentDetails['thumbnail'] = $uvdesk->generateCompleteLocalResourcePathUri($agentDetails['thumbnail'] ?? $defaultAgentProfileImagePath);
}
if (! empty($agentDetails)) {
$customerDetails['thumbnail'] = $uvdesk->generateCompleteLocalResourcePathUri($customerDetails['thumbnail'] ?? $defaultCustomerProfileImagePath);
}
// Mark as viewed by agents
if (false == $ticket->getIsAgentViewed()) {
$ticket
->setIsAgentViewed(true);
$entityManager->persist($ticket);
$entityManager->flush();
}
// Ticket status Collection
$status = array_map(function ($statusCollection) {
return [
'id' => $statusCollection->getId(),
'code' => $statusCollection->getCode(),
'colorCode' => $statusCollection->getColorCode(),
'description' => $statusCollection->getDescription(),
];
}, $entityManager->getRepository(CoreFrameworkBundleEntity\TicketStatus::class)->findAll());
// Ticket Type Collection
$type = array_map(function ($ticketTypeCollection) {
return [
'id' => $ticketTypeCollection->getId(),
'code' => $ticketTypeCollection->getCode(),
'isActive' => $ticketTypeCollection->getIsActive(),
'description' => $ticketTypeCollection->getDescription(),
];
}, $entityManager->getRepository(CoreFrameworkBundleEntity\TicketType::class)->findByIsActive(true));
// Priority Collection
$priority = array_map(function ($ticketPriorityCollection) {
return [
'id' => $ticketPriorityCollection->getId(),
'code' => $ticketPriorityCollection->getCode(),
'colorCode' => $ticketPriorityCollection->getColorCode(),
'description' => $ticketPriorityCollection->getDescription(),
];
}, $entityManager->getRepository(CoreFrameworkBundleEntity\TicketPriority::class)->findAll());
$userService = $container->get('user.service');
$fileSystemService = $container->get('uvdesk.core.file_system.service');
$supportGroup = $ticket->getSupportGroup();
if (! empty($supportGroup)) {
$supportGroup = [
'id' => $supportGroup->getId(),
'name' => $supportGroup->getName(),
];
}
$supportTeam = $ticket->getSupportTeam();
if (! empty($supportTeam)) {
$supportTeam = [
'id' => $supportTeam->getId(),
'name' => $supportTeam->getName(),
];
}
$ticketDetails = [
'id' => $ticket->getId(),
'source' => $ticket->getSource(),
'priority' => $ticket->getPriority()->getId(),
'status' => $ticket->getStatus()->getId(),
'subject' => $ticket->getSubject(),
'isNew' => $ticket->getIsNew(),
'isReplied' => $ticket->getIsReplied(),
'isReplyEnabled' => $ticket->getIsReplyEnabled(),
'isStarred' => $ticket->getIsStarred(),
'isTrashed' => $ticket->getIsTrashed(),
'isAgentViewed' => $ticket->getIsAgentViewed(),
'isCustomerViewed' => $ticket->getIsCustomerViewed(),
'createdAt' => $userService->getLocalizedFormattedTime($ticket->getCreatedAt(), $user),
'updatedAt' => $userService->getLocalizedFormattedTime($ticket->getUpdatedAt(), $user),
'group' => $supportGroup,
'team' => $supportTeam,
];
$threads = array_map(function ($thread) use ($uvdesk, $userService, $fileSystemService, $defaultAgentProfileImagePath, $defaultCustomerProfileImagePath) {
$user = $thread->getUser();
$userInstance = $thread->getCreatedBy() == 'agent' ? $user->getAgentInstance() : $user->getCustomerInstance();
$attachments = array_map(function ($attachment) use ($fileSystemService) {
return $fileSystemService->getFileTypeAssociations($attachment);
}, $thread->getAttachments()->getValues());
$thumbnail = $uvdesk->generateCompleteLocalResourcePathUri($userInstance->getProfileImagePath() ?? ($thread->getCreatedBy() == 'agent' ? $defaultAgentProfileImagePath : $defaultCustomerProfileImagePath));
return [
'id' => $thread->getId(),
'source' => $thread->getSource(),
'threadType' => $thread->getThreadType(),
'createdBy' => $thread->getCreatedBy(),
'cc' => $thread->getCc(),
'bcc' => $thread->getBcc(),
'isLocked' => $thread->getIsLocked(),
'isBookmarked' => $thread->getIsBookmarked(),
'message' => $thread->getMessage(),
'source' => $thread->getSource(),
'createdAt' => $userService->getLocalizedFormattedTime($thread->getCreatedAt(), $user),
'updatedAt' => $userService->getLocalizedFormattedTime($thread->getUpdatedAt(), $user),
'user' => [
'id' => $user->getId(),
'name' => $user->getFullName(),
'email' => $user->getEmail(),
'thumbnail' => $thumbnail,
],
'attachments' => $attachments,
];
}, $ticket->getThreads()->getValues());
$ticketDetails['threads'] = $threads;
$ticketDetails['agent'] = $agentDetails;
$ticketDetails['customer'] = $customerDetails;
$ticketDetails['totalThreads'] = count($threads);
$customFields = [];
if ($userService->isFileExists('apps/uvdesk/custom-fields')) {
$customFieldsService = $this->container->get('uvdesk_package_custom_fields.service');
$customFields = $customFieldsService->getTicketCustomFieldDetails($ticket->getId());
}
return new JsonResponse([
'ticket' => $ticketDetails,
'totalCustomerTickets' => ($ticketRepository->countCustomerTotalTickets($customer, $container)),
'supportGroups' => $userRepository->getSupportGroups(),
'supportTeams' => $userRepository->getSupportTeams(),
'ticketStatuses' => $status,
'ticketPriorities' => $priority,
'ticketTypes' => $type,
'customFields' => $customFields
]);
}
/**
* delete support tickets.
*
* @param Request $request
* @return void
*/
public function deleteTicketForever(Request $request, ContainerInterface $container, EntityManagerInterface $entityManager)
{
$ticketId = $request->attributes->get('ticketId');
$ticket = $entityManager->getRepository(CoreFrameworkBundleEntity\Ticket::class)->find($ticketId);
if (! $ticket) {
throw new NotFoundHttpException('No ticket Found');
}
if ($ticket->getIsTrashed()) {
$entityManager->remove($ticket);
$entityManager->flush();
$json['success'] = $container->get('translator')->trans('Success ! Ticket removed successfully.');
$statusCode = Response::HTTP_OK;
// Trigger ticket delete event
$event = new CoreWorkflowEvents\Ticket\Delete();
$event
->setTicket($ticket);
$container->get('event_dispatcher')->dispatch($event, 'uvdesk.automation.workflow.execute');
} else {
$json['error'] = $container->get('translator')->trans('Warning ! something went wrong.');
$statusCode = Response::HTTP_BAD_REQUEST;
}
return new JsonResponse($json, $statusCode);
}
/**
* Assign Ticket to a agent
*
* @param Request $request
* @return void
*/
public function assignAgent(Request $request, ContainerInterface $container, EntityManagerInterface $entityManager)
{
$json = [];
$data = $request->request->all() ?: json_decode($request->getContent(), true);
$ticketId = $request->attributes->get('ticketId');
$ticket = $entityManager->getRepository(CoreFrameworkBundleEntity\Ticket::class)->findOneBy(array('id' => $ticketId));
if ($ticket) {
if (isset($data['id'])) {
$agent = $entityManager->getRepository(CoreFrameworkBundleEntity\User::class)->find($data['id']);
} else {
$json['error'] = $container->get('translator')->trans('missing fields');
$json['description'] = $container->get('translator')->trans('required: id ');
return new JsonResponse($json, Response::HTTP_BAD_REQUEST);
}
if ($agent) {
if ($ticket->getAgent() != $agent) {
if ($ticket->getIsTrashed()) {
$json['status'] = false;
$json['error'] = $container->get('translator')->trans('Tickets is in trashed can not assign to agent.');
return new JsonResponse($json, Response::HTTP_BAD_REQUEST);
}
$ticket->setAgent($agent);
$entityManager->persist($ticket);
$entityManager->flush();
$json['success'] = $container->get('translator')->trans('Success ! Ticket assigned to agent successfully.');
$statusCode = Response::HTTP_OK;
// Trigger ticket delete event
$event = new CoreWorkflowEvents\Ticket\Agent();
$event
->setTicket($ticket);
$container->get('event_dispatcher')->dispatch($event, 'uvdesk.automation.workflow.execute');
} else {
$json['error'] = $container->get('translator')->trans('invalid resource');
$json['description'] = $container->get('translator')->trans('Error ! Invalid agent or already assigned for this ticket');
$statusCode = Response::HTTP_NOT_FOUND;
}
}
} else {
$json['error'] = $container->get('translator')->trans('invalid ticket');
$statusCode = Response::HTTP_NOT_FOUND;
}
return new JsonResponse($json, $statusCode);
}
/**
* adding or removing collaborator to a Ticket
*
* @param Request $request
* @return void
*/
public function addRemoveTicketCollaborator(Request $request, ContainerInterface $container, EntityManagerInterface $entityManager)
{
$json = [];
$statusCode = Response::HTTP_OK;
$content = $request->request->all() ?: json_decode($request->getContent(), true);
$ticket = $entityManager->getRepository(CoreFrameworkBundleEntity\Ticket::class)->find($request->attributes->get('ticketId'));
if (! $ticket) {
$json['error'] = $container->get('translator')->trans('resource not found');
return new JsonResponse($json, Response::HTTP_NOT_FOUND);
}
if (
$request->getMethod() == "POST"
&& ! (isset($content['id']))
) {
if (
! isset($content['email'])
|| ! filter_var($content['email'], FILTER_VALIDATE_EMAIL)
) {
$json['error'] = $container->get('translator')->trans('missing/invalid field');
$json['message'] = $container->get('translator')->trans('required: email');
return new JsonResponse($json, Response::HTTP_BAD_REQUEST);
}
if ($content['email'] == $ticket->getCustomer()->getEmail()) {
$json['error'] = $container->get('translator')->trans('Error ! Can not add customer as a collaborator.');
$statusCode = Response::HTTP_BAD_REQUEST;
} else {
$data = array(
'from' => $content['email'],
'firstName' => ($firstName = ucfirst(current(explode('@', $content['email'])))),
'lastName' => '',
'role' => 4,
);
$supportRole = $entityManager->getRepository(CoreFrameworkBundleEntity\SupportRole::class)->findOneByCode('ROLE_CUSTOMER');
$collaborator = $container->get('user.service')->createUserInstance($data['from'], $data['firstName'], $supportRole, $extras = ["active" => true]);
$checkTicket = $entityManager->getRepository(CoreFrameworkBundleEntity\Ticket::class)->isTicketCollaborator($ticket, $content['email']);
if (! $checkTicket) {
$ticket->addCollaborator($collaborator);
$entityManager->persist($ticket);
$entityManager->flush();
$ticket->lastCollaborator = $collaborator;
$json['collaborator'] = $collaborator->getCustomerInstance() ? $collaborator->getCustomerInstance()->getPartialDetails() : $collaborator->getAgentInstance()->getPartialDetails();
$event = new CoreWorkflowEvents\Ticket\Collaborator();
$event
->setTicket($ticket);
$container->get('event_dispatcher')->dispatch($event, 'uvdesk.automation.workflow.execute');
$json['success'] = $container->get('translator')->trans('Success ! Collaborator added successfully.');
$statusCode = Response::HTTP_OK;
} else {
$json['warning'] = $container->get('translator')->trans('Collaborator is already added.');
$statusCode = Response::HTTP_BAD_REQUEST;
}
}
} elseif ($request->getMethod() == "POST" && isset($content['id'])) {
$collaborator = $entityManager->getRepository(CoreFrameworkBundleEntity\User::class)->findOneBy(array('id' => $content['id']));
if ($collaborator) {
$ticket->removeCollaborator($collaborator);
$entityManager->persist($ticket);
$entityManager->flush();
$json['success'] = $container->get('translator')->trans('Success ! Collaborator removed successfully.');
$statusCode = Response::HTTP_OK;
} else {
$json['error'] = $container->get('translator')->trans('Error ! Invalid Collaborator.');
$statusCode = Response::HTTP_BAD_REQUEST;
}
}
return new JsonResponse($json, $statusCode);
}
/**
* Download ticket attachment
*
* @param Request $request
* @return void
*/
public function downloadAttachment(Request $request, ContainerInterface $container, EntityManagerInterface $entityManager)
{
$attachmentId = $request->attributes->get('attachmentId');
$attachmentRepository = $entityManager->getRepository(CoreFrameworkBundleEntity\Attachment::class);
$attachment = $attachmentRepository->findOneById($attachmentId);
if (! $attachment) {
throw new NotFoundHttpException('Attachment Not Found');
}
$path = $container->get('kernel')->getProjectDir() . "/public/" . $attachment->getPath();
$response = new Response();
$response->setStatusCode(200);
$response->headers->set('Content-type', $attachment->getContentType());
$response->headers->set('Content-Disposition', 'attachment; filename=' . $attachment->getName());
$response->sendHeaders();
$response->setContent(readfile($path));
return $response;
}
/**
* Download Zip attachment
*
* @param Request $request
* @return void
*/
public function downloadZipAttachment(Request $request, EntityManagerInterface $entityManager)
{
$threadId = $request->attributes->get('threadId');
$attachmentRepository = $entityManager->getRepository(CoreFrameworkBundleEntity\Attachment::class);
$attachment = $attachmentRepository->findByThread($threadId);
if (! $attachment) {
throw new NotFoundHttpException('Page Not Found');
}
$zipname = 'attachments/' . $threadId . '.zip';
$zip = new \ZipArchive;
$zip->open($zipname, \ZipArchive::CREATE);
if (count($attachment)) {
foreach ($attachment as $attach) {
$zip->addFile(substr($attach->getPath(), 1));
}
}
$zip->close();
$response = new Response();
$response->setStatusCode(200);
$response->headers->set('Content-type', 'application/zip');
$response->headers->set('Content-Disposition', 'attachment; filename=' . $threadId . '.zip');
$response->sendHeaders();
$response->setContent(readfile($zipname));
return $response;
}
/**
* Edit Ticket properties
*
* @param Request $request
* @return void
*/
public function editTicketProperties(Request $request, ContainerInterface $container, EntityManagerInterface $entityManager)
{
$json = [];
$statusCode = Response::HTTP_OK;
$requestContent = $request->request->all() ?: json_decode($request->getContent(), true);
$ticketId = $request->attributes->get('ticketId');
$ticket = $entityManager->getRepository(CoreFrameworkBundleEntity\Ticket::class)->findOneById($ticketId);
// Validate request integrity
if (empty($ticket)) {
$json['error'] = 'invalid resource';
$json['description'] = $container->get('translator')->trans('Unable to retrieve details for ticket #%ticketId%.', [
'%ticketId%' => $ticketId,
]);
$statusCode = Response::HTTP_NOT_FOUND;
return new JsonResponse($json, $statusCode);
} else if (!isset($requestContent['property'])) {
$json['error'] = $container->get('translator')->trans('missing resource');
$json['description'] = $container->get('translator')->trans('Insufficient details provided.');
$statusCode = Response::HTTP_BAD_REQUEST;
return new JsonResponse($json, $statusCode);
}
// Update property
switch ($requestContent['property']) {
case 'agent':
$agent = $entityManager->getRepository(CoreFrameworkBundleEntity\User::class)->findOneById($requestContent['value']);
if (empty($agent)) {
// User does not exist
$json['error'] = $container->get('translator')->trans('No such user exist');
$json['description'] = $container->get('translator')->trans('Unable to retrieve agent details');
$statusCode = Response::HTTP_BAD_REQUEST;
return new JsonResponse($json, $statusCode);
} else {
// Check if an agent instance exists for the user
$agentInstance = $agent->getAgentInstance();
if (empty($agentInstance)) {
// Agent does not exist
$json['error'] = $container->get('translator')->trans('No such user exist');
$json['description'] = $container->get('translator')->trans('Unable to retrieve agent details');
$statusCode = Response::HTTP_BAD_REQUEST;
return new JsonResponse($json, $statusCode);
}
}
$agentDetails = $agentInstance->getPartialDetails();
// Check if ticket is already assigned to the agent
if (
$ticket->getAgent()
&& $agent->getId() === $ticket->getAgent()->getId()
) {
$json['success'] = $container->get('translator')->trans('Already assigned');
$json['description'] = $container->get('translator')->trans('Ticket already assigned to %agent%', [
'%agent%' => $agentDetails['name']
]);
$statusCode = Response::HTTP_OK;
return new JsonResponse($json, $statusCode);
} else {
$ticket->setAgent($agent);
$entityManager->persist($ticket);
$entityManager->flush();
// Trigger Agent Assign event
$event = new CoreWorkflowEvents\Ticket\Agent();
$event
->setTicket($ticket);
$container->get('event_dispatcher')->dispatch($event, 'uvdesk.automation.workflow.execute');
$json['success'] = $container->get('translator')->trans('Success');
$json['description'] = $container->get('translator')->trans('Ticket successfully assigned to %agent%', [
'%agent%' => $agentDetails['name'],
]);
$statusCode = Response::HTTP_OK;
return new JsonResponse($json, $statusCode);
}
break;
case 'status':
$ticketStatus = $entityManager->getRepository(CoreFrameworkBundleEntity\TicketStatus::class)->findOneById((int) $requestContent['value']);
if (empty($ticketStatus)) {
// Selected ticket status does not exist
$json['error'] = $container->get('translator')->trans('Error');
$json['description'] = $container->get('translator')->trans('Unable to retrieve status details');
$statusCode = Response::HTTP_BAD_REQUEST;
return new JsonResponse($json, $statusCode);
}
if ($ticketStatus->getId() === $ticket->getStatus()->getId()) {
$json['success'] = $container->get('translator')->trans('Success');
$json['description'] = $container->get('translator')->trans('Ticket status already set to %status%', [
'%status%' => $ticketStatus->getDescription()
]);
$statusCode = Response::HTTP_OK;
return new JsonResponse($json, $statusCode);
} else {
$ticket->setStatus($ticketStatus);
$entityManager->persist($ticket);
$entityManager->flush();
// Trigger ticket status event
$event = new CoreWorkflowEvents\Ticket\Status();
$event
->setTicket($ticket);
$container->get('event_dispatcher')->dispatch($event, 'uvdesk.automation.workflow.execute');
$json['success'] = $container->get('translator')->trans('Success');
$json['description'] = $container->get('translator')->trans('Ticket status update to %status%', [
'%status%' => $ticketStatus->getDescription()
]);
$statusCode = Response::HTTP_OK;
return new JsonResponse($json, $statusCode);
}
break;
case 'priority':
$ticketPriority = $entityManager->getRepository(CoreFrameworkBundleEntity\TicketPriority::class)->findOneById($requestContent['value']);
if (empty($ticketPriority)) {
// Selected ticket priority does not exist
$json['error'] = $container->get('translator')->trans('Error');
$json['description'] = $container->get('translator')->trans('Unable to retrieve priority details');
$statusCode = Response::HTTP_BAD_REQUEST;
return new JsonResponse($json, $statusCode);
}
if ($ticketPriority->getId() === $ticket->getPriority()->getId()) {
$json['success'] = $container->get('translator')->trans('Success');
$json['description'] = $container->get('translator')->trans('Ticket priority already set to %priority%', [
'%priority%' => $ticketPriority->getDescription()
]);
$statusCode = Response::HTTP_OK;
return new JsonResponse($json, $statusCode);
} else {
$ticket->setPriority($ticketPriority);
$entityManager->persist($ticket);
$entityManager->flush();
// Trigger ticket Priority event
$event = new CoreWorkflowEvents\Ticket\Priority();
$event
->setTicket($ticket);
$container->get('event_dispatcher')->dispatch($event, 'uvdesk.automation.workflow.execute');
$json['success'] = $container->get('translator')->trans('Success');
$json['description'] = $container->get('translator')->trans('Ticket priority updated to %priority%', [
'%priority%' => $ticketPriority->getDescription()
]);
$statusCode = Response::HTTP_OK;
return new JsonResponse($json, $statusCode);
}
break;
case 'group':
$supportGroup = $entityManager->getRepository(CoreFrameworkBundleEntity\SupportGroup::class)->findOneById($requestContent['value']);
if (empty($supportGroup)) {
if ($requestContent['value'] == "") {
if ($ticket->getSupportGroup() != null) {
$ticket->setSupportGroup(null);
$entityManager->persist($ticket);
$entityManager->flush();
}
$json['success'] = $container->get('translator')->trans('Success');
$json['description'] = $container->get('translator')->trans('Ticket support group updated successfully');
$statusCode = Response::HTTP_OK;
} else {
$json['error'] = $container->get('translator')->trans('Error');
$json['description'] = $container->get('translator')->trans('Unable to retrieve support group details');
$statusCode = Response::HTTP_BAD_REQUEST;
}
return new JsonResponse($json, $statusCode);
}
if (
! empty($ticket->getSupportGroup())
&& $supportGroup->getId() === $ticket->getSupportGroup()->getId()
) {
$json['success'] = $container->get('translator')->trans('Success');
$json['description'] = $container->get('translator')->trans('Ticket already assigned to support group');
$statusCode = Response::HTTP_OK;
return new JsonResponse($json, $statusCode);
} else {
$ticket->setSupportGroup($supportGroup);
$entityManager->persist($ticket);
$entityManager->flush();
// Trigger Support group event
$event = new CoreWorkflowEvents\Ticket\Group();
$event
->setTicket($ticket);
$container->get('event_dispatcher')->dispatch($event, 'uvdesk.automation.workflow.execute');
$json['success'] = $container->get('translator')->trans('Success');
$json['description'] = $container->get('translator')->trans('Ticket assigned to support group successfully');
$json['description'] = $container->get('translator')->trans('Ticket assigned to support group %group%', [
'%group%' => $supportGroup->getDescription()
]);
$statusCode = Response::HTTP_OK;
return new JsonResponse($json, $statusCode);
}
break;
case 'team':
$supportTeam = $entityManager->getRepository(CoreFrameworkBundleEntity\SupportTeam::class)->findOneById($requestContent['value']);
if (empty($supportTeam)) {
if ($requestContent['value'] == "") {
if ($ticket->getSupportTeam() != null) {
$ticket->setSupportTeam(null);
$entityManager->persist($ticket);
$entityManager->flush();
}
$json['success'] = $container->get('translator')->trans('Success');
$json['description'] = $container->get('translator')->trans('Ticket support team updated successfully');
$statusCode = Response::HTTP_OK;
return new JsonResponse($json, $statusCode);
} else {
$json['error'] = $container->get('translator')->trans('Error');
$json['description'] = $container->get('translator')->trans('Unable to retrieve support team details');
$statusCode = Response::HTTP_BAD_REQUEST;
return new JsonResponse($json, $statusCode);
}
}
if (
! empty($ticket->getSupportTeam())
&& $supportTeam->getId() === $ticket->getSupportTeam()->getId()
) {
$json['success'] = $container->get('translator')->trans('Success');
$json['description'] = $container->get('translator')->trans('Ticket already assigned to support team');
$statusCode = Response::HTTP_OK;
return new JsonResponse($json, $statusCode);
} else {
$ticket->setSupportTeam($supportTeam);
$entityManager->persist($ticket);
$entityManager->flush();
// Trigger ticket delete event
$event = new CoreWorkflowEvents\Ticket\Team();
$event
->setTicket($ticket);
$container->get('event_dispatcher')->dispatch($event, 'uvdesk.automation.workflow.execute');
$json['success'] = $container->get('translator')->trans('Success');
$json['description'] = $container->get('translator')->trans('Ticket assigned to support team successfully');
$json['description'] = $container->get('translator')->trans('Ticket assigned to support team %team%', [
'%team%' => $supportTeam->getDescription()
]);
$statusCode = Response::HTTP_OK;
return new JsonResponse($json, $statusCode);
}
break;
case 'type':
$ticketType = $entityManager->getRepository(CoreFrameworkBundleEntity\TicketType::class)->findOneById($requestContent['value']);
if (empty($ticketType)) {
// Selected ticket priority does not exist
$json['error'] = $container->get('translator')->trans('Error');
$json['description'] = $container->get('translator')->trans('Unable to retrieve ticket type details');
$statusCode = Response::HTTP_BAD_REQUEST;
return new JsonResponse($json, $statusCode);
}
if (
! empty($ticket->getType())
&& $ticketType->getId() === $ticket->getType()->getId()
) {
$json['success'] = $container->get('translator')->trans('Success');
$json['description'] = $container->get('translator')->trans('Ticket type already set to ' . $ticketType->getDescription());
$statusCode = Response::HTTP_OK;
return new JsonResponse($json, $statusCode);
} else {
$ticket->setType($ticketType);
$entityManager->persist($ticket);
$entityManager->flush();
// Trigger ticket delete event
$event = new CoreWorkflowEvents\Ticket\Type();
$event
->setTicket($ticket);
$container->get('event_dispatcher')->dispatch($event, 'uvdesk.automation.workflow.execute');
$json['success'] = $container->get('translator')->trans('Success');
$json['description'] = $container->get('translator')->trans('Ticket type updated to ' . $ticketType->getDescription());
$statusCode = Response::HTTP_OK;
return new JsonResponse($json, $statusCode);
}
break;
case 'label':
$label = $entityManager->getRepository(CoreFrameworkBundleEntity\SupportLabel::class)->find($requestContent['value']);
if ($label) {
$ticket->removeSupportLabel($label);
$entityManager->persist($ticket);
$entityManager->flush();
$json['success'] = $container->get('translator')->trans('Success');
$json['description'] = $container->get('translator')->trans('Success ! Ticket to label removed successfully');
$statusCode = Response::HTTP_OK;
return new JsonResponse($json, $statusCode);
} else {
$json['error'] = $container->get('translator')->trans('Error');
$json['description'] = $container->get('translator')->trans('No support level exist for this ticket with this id');
$statusCode = Response::HTTP_BAD_REQUEST;
return new JsonResponse($json, $statusCode);
}
break;
default:
break;
}
return new JsonResponse($json, $statusCode);
}
/**
* objectSerializer This function convert Entity object into json contenxt
* @param Object $object Customer Entity object
* @return JSON JSON context
*/
public function objectSerializer($object)
{
$object->formatedCreatedAt = new \Datetime;
$encoders = array(new XmlEncoder(), new JsonEncoder());
$normalizer = new ObjectNormalizer();
$normalizers = array($normalizer);
$serializer = new Serializer($normalizers, $encoders);
$jsonContent = $serializer->serialize($object, 'json', [
'circular_reference_handler' => function ($object) {
return $object->getId();
}
]);
return $jsonContent;
}
}