Created
June 17, 2020 09:35
-
-
Save cawa87/b219571c88490e02714bd779f7fed269 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Ronte\TicketBundle\Entity; | |
use Doctrine\Common\Collections\ArrayCollection; | |
use Doctrine\Common\Collections\Collection; | |
use Doctrine\ORM\Mapping as ORM; | |
use Gedmo\Mapping\Annotation as Gedmo; | |
use Gedmo\SoftDeleteable\Traits\SoftDeleteable; | |
use Ronte\UserBundle\Entity\User; | |
use Symfony\Component\Serializer\Annotation as Serializer; | |
use Symfony\Component\Validator\Constraints as Assert; | |
/** | |
* Ticket | |
* | |
* @ORM\Table(name="tickets") | |
* @ORM\Entity(repositoryClass="Ronte\TicketBundle\Repository\TicketRepository") | |
* @Gedmo\SoftDeleteable(fieldName="deletedAt") | |
*/ | |
class Ticket | |
{ | |
use SoftDeleteable; | |
public const TYPE_JURIDICAL = 1; | |
public const TYPE_PHYSICAL = 2; | |
public const TYPES = [ | |
self::TYPE_JURIDICAL => 'JURIDICAL', | |
self::TYPE_PHYSICAL => 'PHYSICAL', | |
]; | |
/** | |
* @var int | |
* | |
* @ORM\Column(name="id", type="integer") | |
* @ORM\Id | |
* @ORM\GeneratedValue(strategy="AUTO") | |
* | |
* @Serializer\Groups({"Ticket", "TicketChat", "post_chats_out", "get_chats_out", "put_chats_out"}) | |
*/ | |
private $id; | |
/** | |
* @var \DateTime | |
* | |
* @ORM\Column(type="datetime") | |
* | |
* @Gedmo\Timestampable(on="create") | |
* | |
* @Serializer\Groups({"Ticket"}) | |
*/ | |
protected $createdAt; | |
/** | |
* @var \DateTime | |
* | |
* @ORM\Column(type="datetime") | |
* | |
* @Gedmo\Timestampable(on="update") | |
* | |
* @Serializer\Groups({"Ticket"}) | |
*/ | |
protected $updatedAt; | |
/** | |
* @var \DateTime | |
* | |
* @ORM\Column(type="datetime", nullable=true) | |
* | |
* @Serializer\Groups({"Ticket"}) | |
*/ | |
protected $closedAt; | |
/** | |
* @var \DateTime | |
* | |
* @ORM\Column(name="deleted_at", type="datetime", nullable=true) | |
*/ | |
protected $deletedAt; | |
/** | |
* @var string | |
* | |
* @ORM\Column(name="subject", type="string", length=255) | |
* | |
* @Serializer\Groups({"Ticket", "post_ticket", "put_ticket", "post_chats_out", "get_chats_out", "put_chats_out"}) | |
* | |
* @Assert\NotBlank | |
* @Assert\Length(max = 255) | |
*/ | |
private $subject; | |
/** | |
* @var string | |
* | |
* @ORM\Column(name="body", type="text", nullable=true) | |
* | |
* @Serializer\Groups({"Ticket", "post_ticket", "put_ticket"}) | |
*/ | |
private $body; | |
/** | |
* @var TicketStatus | |
* | |
* @ORM\ManyToOne(targetEntity="TicketStatus") | |
* @ORM\JoinColumn(name="status_id", referencedColumnName="id", nullable=false) | |
* | |
* @Serializer\Groups({"Ticket", "post_ticket", "put_ticket", "post_chats_out", "get_chats_out", "put_chats_out"}) | |
* @Assert\Type("Ronte\TicketBundle\Entity\TicketStatus") | |
* @Assert\Valid | |
* @Assert\NotNull | |
*/ | |
private $status; | |
/** | |
* @var User | |
* | |
* @ORM\ManyToOne(targetEntity="Ronte\UserBundle\Entity\User") | |
* @ORM\JoinColumn(name="assign_id", referencedColumnName="id", nullable=false) | |
* | |
* @Serializer\Groups({"ChatShort", "post_ticket", "put_ticket"}) | |
* @Assert\Type("Ronte\UserBundle\Entity\User") | |
* @Assert\Valid | |
* @Assert\NotNull | |
*/ | |
private $assign; | |
/** | |
* @var User | |
* | |
* @ORM\ManyToOne(targetEntity="Ronte\UserBundle\Entity\User") | |
* @ORM\JoinColumn(name="client_user_id", referencedColumnName="id", nullable=false) | |
* | |
* @Serializer\Groups({"ChatShort", "post_ticket", "put_ticket"}) | |
* @Assert\Type("Ronte\UserBundle\Entity\User") | |
* @Assert\Valid | |
* @Assert\NotNull | |
*/ | |
private $clientUser; | |
/** | |
* @var User|null | |
* | |
* @ORM\ManyToOne(targetEntity="Ronte\UserBundle\Entity\User") | |
* @ORM\JoinColumn(name="founder_id", referencedColumnName="id", nullable=true) | |
* | |
* @Serializer\Groups({"ChatShort", "post_ticket"}) | |
* @Assert\Type("Ronte\UserBundle\Entity\User") | |
* @Assert\Valid | |
*/ | |
private $founder; | |
/** | |
* @var TicketCategory | |
* | |
* @ORM\ManyToOne(targetEntity="TicketCategory") | |
* @ORM\JoinColumn(name="category_id", referencedColumnName="id", nullable=false) | |
* | |
* @Serializer\Groups({"Ticket", "post_ticket", "put_ticket"}) | |
* | |
* @Assert\Type("Ronte\TicketBundle\Entity\TicketCategory") | |
* @Assert\Valid | |
* @Assert\NotNull | |
*/ | |
private $category; | |
/** | |
* @var int | |
* | |
* @ORM\Column(name="type", type="integer") | |
* | |
* @Serializer\Groups({"Ticket", "post_ticket", "put_ticket"}) | |
* | |
* @Assert\Choice({Ticket::TYPE_PHYSICAL, Ticket::TYPE_JURIDICAL}, strict=true) | |
*/ | |
private $type = self::TYPE_PHYSICAL; | |
/** | |
* @var ArrayCollection | |
* | |
* @ORM\OneToMany(targetEntity="Ronte\TicketBundle\Entity\TicketChat", mappedBy="ticket") | |
*/ | |
protected $ticketChats; | |
/** | |
* Constructor | |
*/ | |
public function __construct() | |
{ | |
$this->ticketChats = new ArrayCollection(); | |
} | |
/** | |
* Get id. | |
* | |
* @return int | |
*/ | |
public function getId() | |
{ | |
return $this->id; | |
} | |
/** | |
* @return \DateTime | |
*/ | |
public function getCreatedAt(): \DateTime | |
{ | |
return $this->createdAt; | |
} | |
/** | |
* @param \DateTime $createdAt | |
* @return Ticket | |
*/ | |
public function setCreatedAt(\DateTime $createdAt): self | |
{ | |
$this->createdAt = $createdAt; | |
return $this; | |
} | |
/** | |
* @return \DateTime | |
*/ | |
public function getUpdatedAt(): \DateTime | |
{ | |
return $this->updatedAt; | |
} | |
/** | |
* @param \DateTime $updatedAt | |
* @return Ticket | |
*/ | |
public function setUpdatedAt(\DateTime $updatedAt): self | |
{ | |
$this->updatedAt = $updatedAt; | |
return $this; | |
} | |
/** | |
* @return \DateTime|null | |
*/ | |
public function getClosedAt(): ?\DateTime | |
{ | |
return $this->closedAt; | |
} | |
/** | |
* @param \DateTime|null $closedAt | |
* @return Ticket | |
*/ | |
public function setClosedAt(\DateTime $closedAt = null): self | |
{ | |
$this->closedAt = $closedAt; | |
return $this; | |
} | |
/** | |
* @param string $subject | |
* @return $this | |
*/ | |
public function setSubject(string $subject): self | |
{ | |
$this->subject = $subject; | |
return $this; | |
} | |
/** | |
* @return string | |
*/ | |
public function getSubject(): string | |
{ | |
return $this->subject; | |
} | |
/** | |
* Set body. | |
* | |
* @param string|null $body | |
* | |
* @return Ticket | |
*/ | |
public function setBody($body = null): self | |
{ | |
$this->body = $body; | |
return $this; | |
} | |
/** | |
* Get body. | |
* | |
* @return string|null | |
*/ | |
public function getBody(): ?string | |
{ | |
return $this->body; | |
} | |
/** | |
* Set status. | |
* | |
* @param TicketStatus $status | |
* | |
* @return Ticket | |
*/ | |
public function setStatus(TicketStatus $status): self | |
{ | |
$this->status = $status; | |
return $this; | |
} | |
/** | |
* Get status. | |
* | |
* @return TicketStatus | |
*/ | |
public function getStatus(): TicketStatus | |
{ | |
return $this->status; | |
} | |
/** | |
* Set assign. | |
* | |
* @param User $assign | |
* | |
* @return Ticket | |
*/ | |
public function setAssign(User $assign): self | |
{ | |
$this->assign = $assign; | |
return $this; | |
} | |
/** | |
* Get assign. | |
* | |
* @return User | |
*/ | |
public function getAssign(): User | |
{ | |
return $this->assign; | |
} | |
/** | |
* Set clientUser. | |
* | |
* @param User $clientUser | |
* | |
* @return Ticket | |
*/ | |
public function setClientUser(User $clientUser): self | |
{ | |
$this->clientUser = $clientUser; | |
return $this; | |
} | |
/** | |
* Get clientUser. | |
* | |
* @return User | |
*/ | |
public function getClientUser(): User | |
{ | |
return $this->clientUser; | |
} | |
/** | |
* Set founder. | |
* | |
* @param User|null $founder | |
* | |
* @return Ticket | |
*/ | |
public function setFounder(User $founder = null): self | |
{ | |
$this->founder = $founder; | |
return $this; | |
} | |
/** | |
* Get founder. | |
* | |
* @return User|null | |
*/ | |
public function getFounder(): ?User | |
{ | |
return $this->founder; | |
} | |
/** | |
* Set category. | |
* | |
* @param TicketCategory $category | |
* | |
* @return Ticket | |
*/ | |
public function setCategory(TicketCategory $category): self | |
{ | |
$this->category = $category; | |
return $this; | |
} | |
/** | |
* Get category. | |
* | |
* @return TicketCategory | |
*/ | |
public function getCategory(): TicketCategory | |
{ | |
return $this->category; | |
} | |
/** | |
* Set type. | |
* | |
* @param int $type | |
* | |
* @return Ticket | |
*/ | |
public function setType(int $type): self | |
{ | |
$this->type = $type; | |
return $this; | |
} | |
/** | |
* Get type. | |
* | |
* @return int | |
*/ | |
public function getType(): int | |
{ | |
return $this->type; | |
} | |
public function getTicketChats(): Collection | |
{ | |
return $this->ticketChats; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Ronte\ChatsBundle\Controller; | |
use FOS\RestBundle\Controller\Annotations as Rest; | |
use FOS\RestBundle\Controller\FOSRestController; | |
use FOS\RestBundle\Request\ParamFetcherInterface; | |
use Ronte\ChatsBundle\Entity\Chat; | |
use Ronte\ChatsBundle\Entity\Message; | |
use Ronte\ChatsBundle\Event\MessageDeliveredEvent; | |
use Ronte\ChatsBundle\Event\MessagesReadEvent; | |
use Ronte\ChatsBundle\Exception\AccessDeniedException; | |
use Ronte\ChatsBundle\Exception\BadRequestHttpException; | |
use Ronte\ChatsBundle\Exception\ConflictViolationException; | |
use Ronte\ChatsBundle\Exception\ConstraintViolationException; | |
use Ronte\ChatsBundle\Manager\MessageManager; | |
use Ronte\UserBundle\Entity\Session; | |
use Ronte\UserBundle\Entity\User; | |
use Ronte\UserBundle\Manager\UserManager; | |
use Sensio\Bundle\FrameworkExtraBundle\Configuration as Extra; | |
use Symfony\Component\HttpFoundation\BinaryFileResponse; | |
use Symfony\Component\HttpFoundation\Request; | |
use Symfony\Component\Serializer\Encoder\CsvEncoder; | |
use Symfony\Component\Serializer\Serializer; | |
/** | |
* MessagesController | |
*/ | |
class MessageController extends FOSRestController | |
{ | |
/** | |
* Update messages read | |
* | |
* @Rest\Put("/messages/read", name="put_read", options={"method_prefix"=false}) | |
* @Rest\View(serializerGroups={"put_read_out", "get_files_out"}) | |
* | |
* @param Request $request | |
* | |
* @throws \Symfony\Component\Security\Core\Exception\AccessDeniedException | |
* @throws \Symfony\Component\HttpKernel\Exception\BadRequestHttpException | |
* @throws AccessDeniedException | |
* @throws BadRequestHttpException | |
* @throws ConstraintViolationException | |
* @throws \InvalidArgumentException | |
* @throws \LogicException | |
* | |
* @return Message[] | |
*/ | |
public function putMessagesReadAction(Request $request): array | |
{ | |
$user = $this->getUser(); | |
$manager = $this->getDoctrine()->getManager(); | |
$repository = $this->getDoctrine() | |
->getRepository(Message::class); | |
$body = \json_decode($request->getContent(), true); | |
if (empty($body['ids']) || $body['ids'] !== array_filter($body['ids'], '\is_int')) { | |
throw new BadRequestHttpException('Invalid parameter: ids.'); | |
} | |
if (JSON_ERROR_NONE !== json_last_error()) { | |
throw new BadRequestHttpException('Invalid parameter: json.' . json_last_error()); | |
} | |
$messages = $repository->findBy(['id' => $body['ids']]); | |
if (empty($messages)) { | |
throw new BadRequestHttpException('Wrong parameter: message ids.'); | |
} | |
foreach ($messages as $key => $message) { | |
/** @var Chat $chat */ | |
$chat = $message->getChat(); | |
if (null !== $chat && !$chat->isFounder($user) && !$chat->isResponsible($user)) { | |
throw new AccessDeniedException(); | |
} | |
if ($message->isSender($user)) { | |
unset($messages[$key]); | |
continue; | |
} | |
$message->setReadAt(new \DateTime()); | |
$manager->persist($message); | |
} | |
if (\count($messages)) { | |
$messages = array_values($messages); | |
$manager->flush(); | |
$this->get('event_dispatcher')->dispatch(MessagesReadEvent::NAME, new MessagesReadEvent($messages)); | |
} | |
return $messages; | |
} | |
/** | |
* Update message read | |
* | |
* @Rest\Put("/messages/{id}/read", name="put_message_read", requirements={"id":"\d+"}) | |
* @Rest\View(serializerGroups={"put_read_out", "get_files_out"}) | |
* | |
* @param Message $message | |
* | |
* @throws ConflictViolationException | |
* @throws \LogicException | |
* | |
* @return Message | |
*/ | |
public function putMessageReadAction(Message $message): Message | |
{ | |
/** @var User $user */ | |
$user = $this->getUser(); | |
$userRole = $user->getRole(true); | |
$chat = $message->getChat(); | |
if (null !== $chat && $userRole === 'ROLE_CLIENT' && !$chat->isFounder($user)) { | |
throw new AccessDeniedException(); | |
} | |
if (null !== $chat && $userRole !== 'ROLE_CLIENT' && !$chat->isResponsible($user)) { | |
throw new AccessDeniedException(); | |
} | |
if (null === $chat && $userRole !== 'ROLE_CLIENT') { | |
throw new AccessDeniedException(); | |
} | |
if ($message->isSender($this->getUser())) { | |
throw new ConflictViolationException('Can`t read own message', 'supportMessageRead'); | |
} | |
$manager = $this->getDoctrine()->getManager(); | |
$message->setReadAt(new \DateTime()); | |
$manager->persist($message); | |
$manager->flush(); | |
$this->get('event_dispatcher')->dispatch(MessagesReadEvent::NAME, new MessagesReadEvent([$message])); | |
return $message; | |
} | |
/** | |
* Get messages | |
* | |
* @Rest\Get("/messages", name="get_messages_2", options={"method_prefix"=false}) | |
* @Rest\QueryParam(name="sessionId", requirements="\d+", nullable=true, description="Required for clients") | |
* @Rest\QueryParam(name="chatId", requirements="\d+", nullable=true) | |
* @Rest\QueryParam(name="offset", requirements="\d+", nullable=true, default="0") | |
* @Rest\QueryParam(name="limit", requirements="\d+", nullable=true, default="1000") | |
* @Rest\QueryParam(name="id_gt", requirements="\d+", nullable=true, description="Greater then given id") | |
* @Rest\QueryParam(name="id_lt", requirements="\d+", nullable=true, description="Less then given id") | |
* @Rest\QueryParam(name="sort", nullable=true, description="Allownd alues: 'id' sort by id ASC, '-id' sort by id DESC") | |
* | |
* @Rest\View(serializerGroups={"get_messages_out", "get_files_out"}) | |
* | |
* @Extra\Security("has_role('ROLE_CLIENT') or has_role('ROLE_OPERATOR1')") | |
* | |
* @param ParamFetcherInterface $paramFetcher | |
* | |
* @throws \Symfony\Component\HttpKernel\Exception\BadRequestHttpException | |
* @throws \Symfony\Component\Security\Core\Exception\AccessDeniedException | |
* @throws \LogicException | |
* @throws \Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException | |
* @throws BadRequestHttpException | |
* @throws AccessDeniedException | |
* | |
* @return Message[] | |
*/ | |
public function getMessagesListAction(ParamFetcherInterface $paramFetcher): array | |
{ | |
$user = $this->getUser(); | |
$authChecker = $this->get('security.authorization_checker'); | |
$sessionId = $paramFetcher->get('sessionId'); | |
if ($authChecker->isGranted('ROLE_CLIENT')) { | |
if (!$sessionId) { | |
throw new BadRequestHttpException('Parameter: sessionId can not be empty'); | |
} | |
if (!$session = $this->getDoctrine()->getRepository(Session::class)->find($sessionId)) { | |
throw new BadRequestHttpException('Parameter: sessionId is invalid.'); | |
} | |
if ($user !== $session->getUser()) { | |
throw new AccessDeniedException(''); | |
} | |
return $this->getDoctrine() | |
->getRepository(Message::class) | |
->findByClientSession($session, $paramFetcher->all()) | |
; | |
} | |
if ($authChecker->isGranted('ROLE_OPERATOR1')) { | |
$operators = $this->get(UserManager::class)->getAvailOperators($user); | |
$operators[] = $user; | |
if ($authChecker->isGranted('ROLE_OPERATOR2')) { | |
$operators[] = null; | |
} | |
return $this->getDoctrine() | |
->getRepository(Message::class) | |
->findForOperators($operators, $paramFetcher->all()); | |
} | |
throw new AccessDeniedException(''); | |
} | |
/** | |
* Get messages | |
* | |
* @Rest\Get("/messages/archive", name="get_messages_archive", options={"method_prefix"=false}) | |
* @Rest\QueryParam(name="username", strict=true) | |
* @Rest\QueryParam(name="app", strict=false) | |
* @Rest\QueryParam(name="product", strict=false) | |
* @Rest\QueryParam(name="format", strict=false) | |
* @Rest\QueryParam(name="from_date", strict=false, requirements="\d+") | |
* @Rest\QueryParam(name="to_date", strict=false, requirements="\d+") | |
* | |
* @Rest\View(serializerGroups={"get_messages_out", "get_files_out"}) | |
* | |
* @Extra\Security("has_role('ROLE_ADMIN') or has_role('ROLE_OPERATOR3')") | |
* | |
* @param ParamFetcherInterface $paramFetcher | |
* | |
* @throws \Symfony\Component\HttpKernel\Exception\BadRequestHttpException | |
* @throws \Symfony\Component\Security\Core\Exception\AccessDeniedException | |
* @throws \LogicException | |
* @throws \Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException | |
* @throws BadRequestHttpException | |
* @throws AccessDeniedException | |
* | |
* @return Message[]|BinaryFileResponse | |
*/ | |
public function getMessagesArchiveAction(ParamFetcherInterface $paramFetcher) | |
{ | |
$messages = $this->get(MessageManager::class)->getArchive($paramFetcher->all()); | |
if ($paramFetcher->get('format') === 'csv') { | |
/** @var Serializer $serializer */ | |
$serializer = $this->get('serializer'); | |
$data = $serializer->serialize($messages, 'csv', [ | |
'groups' => ['get_messages_csv'], | |
CsvEncoder::DELIMITER_KEY => ';' | |
]); | |
$data = mb_convert_encoding($data, 'Windows-1251'); | |
$date = (new \DateTime())->format('Y-m-d_H:i:s.u'); | |
$filename = '/tmp/archive(' . $date . ').csv'; | |
file_put_contents($filename, $data); | |
return $this->file($filename); | |
} | |
return $messages; | |
} | |
/** | |
* Create message | |
* | |
* @Rest\Post("/messages", name="post_message") | |
* @Rest\RequestParam(name="body", strict=false, description="Message body") | |
* @Rest\RequestParam(name="messageType", requirements="^(raw|file)$", strict=false, default="raw", description="Message type") | |
* @Rest\RequestParam(name="sessionId", strict=false, requirements="\d+", description="Required for clients") | |
* @Rest\RequestParam(name="chatId", strict=false, requirements="\d+", description="Required for operators") | |
* @Rest\RequestParam(name="msgId", strict=false, description="Client's UUID") | |
* @Rest\RequestParam(name="files", strict=false, description="User files. Required if messageType=file") | |
* @Rest\View(serializerGroups={"post_messages_out", "get_files_out"}) | |
* | |
* @param ParamFetcherInterface $paramFetcher | |
* | |
* @throws AccessDeniedException | |
* @throws BadRequestHttpException | |
* @throws ConflictViolationException | |
* @throws \Doctrine\ORM\ORMInvalidArgumentException | |
* @throws \LogicException | |
* @throws \Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException | |
* @throws ConstraintViolationException | |
* @throws \Doctrine\ORM\OptimisticLockException | |
* @throws \Doctrine\ORM\NonUniqueResultException | |
* | |
* @return Message | |
*/ | |
public function postMessageAction(ParamFetcherInterface $paramFetcher): Message | |
{ | |
$authChecker = $this->get('security.authorization_checker'); | |
if ($authChecker->isGranted('ROLE_CLIENT')) { | |
$message = $this->get(MessageManager::class)->createByClient($this->getUser(), $paramFetcher->all()); | |
} elseif ($authChecker->isGranted('ROLE_OPERATOR1')) { | |
$message = $this->get(MessageManager::class)->createByOperator($this->getUser(), $paramFetcher->all()); | |
} elseif ($authChecker->isGranted('ROLE_SERVICE')) { | |
$message = $this->get(MessageManager::class)->createByService($this->getUser(), $paramFetcher->all()); | |
} else { | |
throw new AccessDeniedException(); | |
} | |
return $message; | |
} | |
/** | |
* Get unread messages count | |
* | |
* @Rest\Get("/messages/unreadCount", name="get_unread_messages_count") | |
* @Rest\QueryParam(name="sessionId", strict=false, description="Required for clients") | |
* @Rest\QueryParam(name="chatId", strict=false, description="Required for operators") | |
* | |
* @param ParamFetcherInterface $paramFetcher | |
* @throws BadRequestHttpException | |
* @throws AccessDeniedException | |
* @throws \LogicException | |
* @throws \Doctrine\ORM\NoResultException | |
* @throws \Doctrine\ORM\NonUniqueResultException | |
* @return array | |
*/ | |
public function getUnreadMessagesCountAction(ParamFetcherInterface $paramFetcher): array | |
{ | |
$count = $this->get(MessageManager::class)->countUnreadMessages($this->getUser(), $paramFetcher->all()); | |
return [ | |
'count' => $count, | |
]; | |
} | |
/** | |
* Update message read | |
* | |
* @Rest\Put("/messages/{id}/delivered", name="put_message_delivered", requirements={"id":"\d+"}) | |
* @Rest\View(serializerGroups={"put_read_out", "get_files_out"}) | |
* | |
* @param Message $message | |
* | |
* @throws ConflictViolationException | |
* @throws \LogicException | |
* | |
* @return Message | |
*/ | |
public function putMessageDeliveredAction(Message $message): Message | |
{ | |
/** @var User $user */ | |
$user = $this->getUser(); | |
$userRole = $user->getRole(true); | |
$chat = $message->getChat(); | |
if (null !== $chat && $userRole === 'ROLE_CLIENT' && !$chat->isFounder($user)) { | |
throw new AccessDeniedException(); | |
} | |
if (null === $chat && $userRole !== 'ROLE_CLIENT') { | |
throw new AccessDeniedException(); | |
} | |
if ($message->isSender($this->getUser())) { | |
throw new ConflictViolationException('Can`t check as delivered own message', 'supportMessageDelivered'); | |
} | |
$manager = $this->getDoctrine()->getManager(); | |
$message->setDeliveredAt(new \DateTime()); | |
$manager->persist($message); | |
$manager->flush(); | |
$this->get('event_dispatcher')->dispatch(MessageDeliveredEvent::NAME, new MessageDeliveredEvent($message)); | |
return $message; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Ronte\ChatsBundle\Manager; | |
use Doctrine\ORM\EntityManager; | |
use Doctrine\ORM\EntityRepository; | |
use Ronte\ChatsBundle\Entity\ChatStatus; | |
use Ronte\ChatsBundle\Entity\File; | |
use Ronte\ChatsBundle\Event\ChatReopenEvent; | |
use Ronte\ChatsBundle\Event\ChatsAvailabilityUpdateEvent; | |
use Ronte\ChatsBundle\Event\MessagePostByCommandEvent; | |
use Ronte\ChatsBundle\Event\MessagePostEvent; | |
use Ronte\ChatsBundle\Event\MetricsEvent; | |
use Ronte\ChatsBundle\Event\RmqCheckEvent; | |
use Ronte\ChatsBundle\Exception\AccessDeniedException; | |
use Ronte\ChatsBundle\Exception\BadRequestHttpException; | |
use Ronte\ChatsBundle\Exception\ConflictViolationException; | |
use Ronte\ChatsBundle\Repository\ChatRepository; | |
use Ronte\UserBundle\Entity\Application; | |
use Ronte\UserBundle\Entity\Product; | |
use Ronte\UserBundle\Manager\SessionManager; | |
use Ronte\UserBundle\Manager\UserManager; | |
use Symfony\Component\EventDispatcher\EventDispatcherInterface; | |
use Symfony\Component\HttpFoundation\Response; | |
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface; | |
use Symfony\Component\Validator\Validator\ValidatorInterface; | |
use Symfony\Component\Serializer\SerializerInterface; | |
use Ronte\ChatsBundle\Entity\Chat; | |
use Ronte\ChatsBundle\Entity\Message; | |
use Ronte\ChatsBundle\Event\ChatsPostEvent; | |
use Ronte\ChatsBundle\Exception\ConstraintViolationException; | |
use Ronte\UserBundle\Entity\Session; | |
use Ronte\UserBundle\Entity\User; | |
use UAParser\Parser; | |
/** | |
* Class MessageManager | |
* @package Ronte\ChatsBundle\Manager | |
*/ | |
class MessageManager | |
{ | |
/** @var ValidatorInterface */ | |
private $validator; | |
/** @var EntityManager */ | |
private $entityManager; | |
/** @var ChatManager */ | |
private $chatManager; | |
/** @var UserManager */ | |
private $userManager; | |
/** @var SessionManager */ | |
private $sessionManager; | |
/** @var AuthorizationCheckerInterface */ | |
private $authChecker; | |
/** @var EventDispatcherInterface */ | |
private $eventDispatcher; | |
/** @var SerializerInterface*/ | |
protected $serializer; | |
/** @var ChatRepository */ | |
private $chatRepository; | |
/** @var EntityRepository */ | |
private $sessionRepository; | |
/** @var EntityRepository */ | |
private $chatStatusRepository; | |
private $chatReopened = false; | |
/** | |
* MessageManager constructor. | |
* @param ValidatorInterface $validator | |
* @param EntityManager $entityManager | |
* @param ChatManager $chatManager | |
* @param UserManager $userManager | |
* @param SessionManager $sessionManager | |
* @param AuthorizationCheckerInterface $authChecker | |
* @param EventDispatcherInterface $eventDispatcher | |
* @param SerializerInterface $serializer | |
*/ | |
public function __construct( | |
ValidatorInterface $validator, | |
EntityManager $entityManager, | |
ChatManager $chatManager, | |
UserManager $userManager, | |
SessionManager $sessionManager, | |
AuthorizationCheckerInterface $authChecker, | |
EventDispatcherInterface $eventDispatcher, | |
SerializerInterface $serializer | |
) { | |
$this->validator = $validator; | |
$this->entityManager = $entityManager; | |
$this->chatManager = $chatManager; | |
$this->userManager = $userManager; | |
$this->sessionManager = $sessionManager; | |
$this->authChecker = $authChecker; | |
$this->eventDispatcher = $eventDispatcher; | |
$this->serializer = $serializer; | |
$this->chatRepository = $entityManager->getRepository(Chat::class); | |
$this->sessionRepository = $this->entityManager->getRepository(Session::class); | |
$this->chatStatusRepository = $entityManager->getRepository(ChatStatus::class); | |
} | |
/** | |
* @return string | |
*/ | |
public static function uuid(): string | |
{ | |
return sprintf( | |
'%04x%04x-%04x-%04x-%04x-%04x%04x%04x', | |
// 32 bits for "time_low" | |
random_int(0, 0xffff), | |
random_int(0, 0xffff), | |
// 16 bits for "time_mid" | |
random_int(0, 0xffff), | |
// 16 bits for "time_hi_and_version", | |
// four most significant bits holds version number 4 | |
random_int(0, 0x0fff) | 0x4000, | |
// 16 bits, 8 bits for "clk_seq_hi_res", | |
// 8 bits for "clk_seq_low", | |
// two most significant bits holds zero and one for variant DCE1.1 | |
random_int(0, 0x3fff) | 0x8000, | |
// 48 bits for "node" | |
random_int(0, 0xffff), | |
random_int(0, 0xffff), | |
random_int(0, 0xffff) | |
); | |
} | |
/** | |
* @param User $user | |
* @param array $params | |
* @return Message | |
* @throws \Doctrine\ORM\OptimisticLockException | |
* @throws BadRequestHttpException | |
*/ | |
public function createByService(User $user, array $params): Message | |
{ | |
$this->eventDispatcher->dispatch(RmqCheckEvent::NAME, new RmqCheckEvent()); | |
if (empty($params['sessionId'])) { | |
throw new BadRequestHttpException('Parameter: sessionId should not be null.'); | |
} | |
if (empty($params['body'])) { | |
throw new BadRequestHttpException('Parameter: body should not be null.'); | |
} | |
/** @var Session $session */ | |
$session = $this->entityManager | |
->getRepository(Session::class) | |
->find($params['sessionId']); | |
if (!$session) { | |
throw new BadRequestHttpException('Parameter: sessionId is invalid.'); | |
} | |
$message = $this->create([ | |
'body' => $params['body'], | |
'session' => $session, | |
'sender' => $user, | |
]); | |
$this->eventDispatcher->dispatch(MessagePostByCommandEvent::NAME, new MessagePostByCommandEvent($message)); | |
return $message; | |
} | |
/** | |
* @param User $user | |
* @param array $params | |
* @return Message | |
* @throws ConflictViolationException | |
* @throws BadRequestHttpException | |
* @throws ConstraintViolationException | |
* @throws \Doctrine\ORM\ORMInvalidArgumentException | |
* @throws AccessDeniedException | |
* @throws BadRequestHttpException | |
* @throws \Doctrine\ORM\NonUniqueResultException | |
* @throws \Doctrine\ORM\OptimisticLockException | |
*/ | |
public function createByClient(User $user, array $params): Message | |
{ | |
$this->eventDispatcher->dispatch(RmqCheckEvent::NAME, new RmqCheckEvent()); | |
if (empty($params['sessionId'])) { | |
throw new BadRequestHttpException('Parameter: sessionId should not be null.'); | |
} | |
/** @var Session $session */ | |
$session = $this->entityManager | |
->getRepository(Session::class) | |
->find($params['sessionId']); | |
if (!$session) { | |
throw new BadRequestHttpException('Parameter: sessionId is invalid.'); | |
} | |
if ($user !== $session->getUser()) { | |
throw new AccessDeniedException(); | |
} | |
$chat = $this->getChatBySession($session); | |
if (null === $chat) { | |
$chat = $this->chatManager->create([ | |
'session' => $session, | |
'founder' => $user, | |
'status' => ChatStatus::STATUS_UNASSIGNED | |
], false); | |
$uaParsed = (Parser::create())->parse($session->getUa()); | |
$this->create([ | |
'chat' => $chat, | |
'body' => sprintf('Chat started by %s in "%s/%s"', | |
$user->getName(), $uaParsed->toString(), $uaParsed->device->toString() | |
), | |
'session' => $session, | |
'sender' => $user, | |
'type' => Message::TYPE_SYSTEM, | |
]); | |
$this->eventDispatcher->dispatch(ChatsPostEvent::NAME_BY_CLIENT, new ChatsPostEvent($chat, $session)); | |
} | |
$message = $this->create([ | |
'chat' => $chat, | |
'body' => $params['body'] ?? '', | |
'session' => $session, | |
'sender' => $user, | |
'msgId' => $params['msgId'], | |
'type' => $params['messageType'] ?? Message::TYPE_RAW, | |
'files' => $params['files'] ?? [] | |
]); | |
if ($chat->getStatus()->getName() === ChatStatus::STATUS_HOLD) { | |
$greetingMessage = $this->create([ | |
'chat' => $chat, | |
'type' => Message::TYPE_GREETING | |
]); | |
$this->modifiedHoldChat($chat); | |
} | |
$this->eventDispatcher->dispatch(MessagePostEvent::NAME, new MessagePostEvent([$message])); | |
if ($this->chatReopened) { | |
$this->eventDispatcher->dispatch(MetricsEvent::NAME_REOPEN_CHAT, new MetricsEvent($chat)); | |
} | |
if (isset($greetingMessage)) { | |
$this->eventDispatcher->dispatch(MessagePostEvent::NAME, new MessagePostEvent([$greetingMessage])); | |
} | |
$metricEvent = new MetricsEvent($chat); | |
$metricEvent->setMessage($message); | |
$this->eventDispatcher->dispatch( MetricsEvent::NAME_POST_CLIENT_MESSAGE, $metricEvent); | |
return $message; | |
} | |
private function getChatBySession(Session $session): ?Chat | |
{ | |
$chat = $this->chatRepository->findOpenedBySession($session->getId()); | |
if (null !== $chat) { | |
return $chat; | |
} | |
$chat = $this->chatRepository->findLastClosedBySession($session->getId(), new \DateTime('-7 days')); | |
$operator = $chat ? $chat->getResponsible() : null; | |
if (null !== $operator && $operator->isOnlineOperator() && $operator->getActive()) { | |
$activeChatsCount = $this->chatRepository->countActiveByOperator($operator); | |
if ($activeChatsCount < 5) { | |
$activeStatus = $this->chatStatusRepository->findOneBy(['name' => ChatStatus::STATUS_ACTIVE]); | |
$chat->setStatus($activeStatus); | |
$this->entityManager->flush($chat); | |
$opSession = $this->sessionManager->getOperatorsSession($operator); | |
$this->eventDispatcher->dispatch(ChatReopenEvent::NAME_CLIENT, new ChatReopenEvent($chat, $session, $opSession)); | |
$this->chatReopened = true; | |
return $chat; | |
} | |
} | |
return null; | |
} | |
/** | |
* @param Chat $chat | |
* @throws \Doctrine\ORM\ORMInvalidArgumentException | |
* @throws \Doctrine\ORM\OptimisticLockException | |
*/ | |
private function modifiedHoldChat(Chat $chat): void | |
{ | |
$statusActive = $this->chatStatusRepository->findOneBy(['name' => ChatStatus::STATUS_ACTIVE]); | |
$chat->setStatus($statusActive); | |
$chat->setFrozenTill(null); | |
$this->entityManager->persist($chat); | |
$this->entityManager->flush($chat); | |
$this->eventDispatcher->dispatch(ChatsAvailabilityUpdateEvent::NAME, new ChatsAvailabilityUpdateEvent($chat)); | |
$this->eventDispatcher->dispatch(MetricsEvent::NAME_UNHOLD_CHAT, new MetricsEvent($chat)); | |
} | |
/** | |
* @param User $user | |
* @param array $params | |
* @return Message | |
* @throws \Ronte\ChatsBundle\Exception\ConstraintViolationException | |
* @throws \Doctrine\ORM\ORMInvalidArgumentException | |
* @throws \Ronte\ChatsBundle\Exception\ConflictViolationException | |
* @throws \Ronte\ChatsBundle\Exception\AccessDeniedException | |
* @throws \Ronte\ChatsBundle\Exception\BadRequestHttpException | |
* @throws \Doctrine\ORM\OptimisticLockException | |
*/ | |
public function createByOperator(User $user, array $params): Message | |
{ | |
$chatId = $params['chatId'] ?? null; | |
if (!$chatId) { | |
throw new BadRequestHttpException('Parameter: chatId can not be null'); | |
} | |
/** @var Chat $chat */ | |
$chat = $this->chatRepository->find($chatId); | |
if (null === $chat) { | |
throw new BadRequestHttpException('Parameter: chatId is invalid'); | |
} | |
if ($chat->getResponsible() !== $user) { | |
throw new AccessDeniedException(); | |
} | |
if ($chat->getStatus()->getName() === ChatStatus::STATUS_CLOSED) { | |
throw new ConflictViolationException( | |
'Chat closed!', | |
'supportChat', | |
null, | |
Response::HTTP_LENGTH_REQUIRED | |
); | |
} | |
if ($chat->getStatus()->getName() === ChatStatus::STATUS_HOLD) { | |
$this->modifiedHoldChat($chat); | |
} | |
$message = $this->create([ | |
'chat' => $chat, | |
'body' => $params['body'] ?? '', | |
'session' => $chat->getSession(), | |
'sender' => $user, | |
'msgId' => $params['msgId'], | |
'type' => $params['messageType'] ?? Message::TYPE_RAW, | |
'files' => $params['files'] ?? [] | |
]); | |
$this->eventDispatcher->dispatch(MessagePostEvent::NAME, new MessagePostEvent([$message])); | |
$metricEvent = new MetricsEvent($chat); | |
$metricEvent->setMessage($message); | |
$this->eventDispatcher->dispatch( MetricsEvent::NAME_POST_OPERATOR_MESSAGE, $metricEvent); | |
return $message; | |
} | |
/** | |
* @param array $params | |
* @param bool $flush | |
* @return Message | |
* @throws \Ronte\ChatsBundle\Exception\ConstraintViolationException | |
* @throws \Doctrine\ORM\ORMInvalidArgumentException | |
* @throws \Ronte\ChatsBundle\Exception\ConflictViolationException | |
* @throws \Ronte\ChatsBundle\Exception\BadRequestHttpException | |
* @throws \Doctrine\ORM\OptimisticLockException | |
*/ | |
public function create(array $params, $flush = true): ?Message | |
{ | |
$this->eventDispatcher->dispatch(RmqCheckEvent::NAME, new RmqCheckEvent()); | |
$params['body'] = isset($params['body']) ? trim($params['body']) : ''; | |
$params['type'] = $params['type'] ?? Message::TYPE_RAW; | |
$chat = $params['chat'] ?? null; | |
//validate messageType.raw | |
if (($params['type'] == Message::TYPE_RAW) && $params['body'] === '') { | |
throw new BadRequestHttpException('Parameter: body should not be empty.'); | |
} | |
if (($params['type'] == Message::TYPE_GREETING)) { | |
if (!$greeting = $this->chatManager->getGreeting($chat)) { | |
return null; | |
} | |
$params['body'] = $greeting->getMessage(); | |
$params['session'] = $chat->getSession(); | |
$params['sender'] = $chat->getResponsible() ?? $this->userManager->getBotUser(); | |
if (null === $params['sender']) { | |
throw new ConflictViolationException('Cant find chats responsible or bot user!'); | |
} | |
} | |
/** @var Message $message */ | |
$message = $this->serializer | |
->deserialize( | |
json_encode($params), | |
Message::class, | |
'json', | |
[ | |
'enable_max_depth' => true, | |
'groups' => ['post_messages_in'], | |
] | |
); | |
$message->setChat($chat); | |
$message->setType($params['type']); | |
$message->setSession($params['session']); | |
$message->setSender($params['sender']); | |
//validate messageType.file | |
if ($params['type'] == Message::TYPE_FILE) { | |
if (empty($params['files'])) { | |
throw new BadRequestHttpException('Parameter: files can not be empty'); | |
} | |
$fileRepository = $this->entityManager->getRepository(File::class); | |
foreach ($params['files'] as $fileId) { | |
$file = $fileRepository->find($fileId); | |
if ($file === null) { | |
throw new ConflictViolationException( | |
sprintf('Parameter: files %d incorrect', $fileId), | |
'supportMessage', | |
null, | |
404, | |
['files' => $fileId] | |
); | |
} | |
if (!$file->isOwner($params['sender'])) { | |
throw new ConflictViolationException( | |
sprintf('Parameter: files no access to file %d', $fileId), | |
'supportMessage', | |
null, | |
410, | |
['files' => $fileId] | |
); | |
} | |
$message->addFile($file); | |
} | |
} | |
if (!empty($params['msgId'])) { | |
$message->setMsgId($params['msgId']); | |
} | |
$errors = $this->validator | |
->validate($message, null, ['post_messages_in']); | |
if (\count($errors)) { | |
throw new ConstraintViolationException($errors); | |
} | |
$this->entityManager->persist($message); | |
if ($flush) { | |
$this->entityManager->flush(); | |
} | |
return $message; | |
} | |
/** | |
* @param User $user | |
* @param array $params | |
* @return int | |
* @throws \Ronte\ChatsBundle\Exception\AccessDeniedException | |
* @throws \Ronte\ChatsBundle\Exception\BadRequestHttpException | |
* @throws \Doctrine\ORM\NoResultException | |
* @throws \Doctrine\ORM\NonUniqueResultException | |
*/ | |
public function countUnreadMessages(User $user, array $params): int | |
{ | |
$sessionId = !empty($params['sessionId']) ? $params['sessionId'] : null; | |
$chatId = !empty($params['chatId']) ? $params['chatId'] : null; | |
if ($this->authChecker->isGranted('ROLE_CLIENT')) { | |
if (!$sessionId) { | |
throw new BadRequestHttpException('Parameter: sessionId can not be empty'); | |
} | |
if (!$session = $this->sessionRepository->find($sessionId)) { | |
throw new BadRequestHttpException('Parameter: sessionId is invalid.'); | |
} | |
if ($user !== $session->getUser()) { | |
throw new AccessDeniedException(); | |
} | |
} elseif ($this->authChecker->isGranted('ROLE_OPERATOR1')) { | |
if (!$chatId) { | |
throw new BadRequestHttpException('Parameter: chatId can not be empty'); | |
} | |
if (!$chat = $this->chatRepository->find($chatId)) { | |
throw new BadRequestHttpException('Parameter: chatId is invalid.'); | |
} | |
} | |
$count = $this->entityManager | |
->getRepository(Message::class) | |
->getCountUnreadMessages($user, $sessionId, $chatId) | |
; | |
return (int)$count; | |
} | |
public function getArchive(array $params) | |
{ | |
$em = $this->entityManager; | |
$username = $params['username'] ?? null; | |
$filters = []; | |
$user = $this->userManager->findClientByUsername($username); | |
if (null === $user) { | |
throw new BadRequestHttpException('Client not found.'); | |
} | |
if (!empty($params['app'])) { | |
$filters['app'] = $em->getRepository(Application::class)->findOneBy(['code' => $params['app']]); | |
if (null === $filters['app']) { | |
throw new BadRequestHttpException('Parameter: app is invalid.'); | |
} | |
} | |
if (!empty($params['product'])) { | |
$filters['product'] = $em->getRepository(Product::class)->findOneBy(['code' => $params['product']]); | |
if (null === $filters['product']) { | |
throw new BadRequestHttpException('Parameter: product is invalid.'); | |
} | |
} | |
if (!empty($params['from_date'])) { | |
$filters['from_date'] = (new \DateTime())->setTimestamp($params['from_date']); | |
} | |
if (!empty($params['to_date'])) { | |
$filters['to_date'] = (new \DateTime())->setTimestamp($params['to_date']); | |
} | |
return $this->entityManager->getRepository(Message::class)->findClientArchive($user, $filters); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Ronte\TicketBundle\Entity; | |
use Doctrine\Common\Collections\ArrayCollection; | |
use Doctrine\Common\Collections\Collection; | |
use Doctrine\ORM\Mapping as ORM; | |
use Gedmo\Mapping\Annotation as Gedmo; | |
use Gedmo\SoftDeleteable\Traits\SoftDeleteable; | |
use Ronte\UserBundle\Entity\User; | |
use Symfony\Component\Serializer\Annotation as Serializer; | |
use Symfony\Component\Validator\Constraints as Assert; | |
/** | |
* Ticket | |
* | |
* @ORM\Table(name="tickets") | |
* @ORM\Entity(repositoryClass="Ronte\TicketBundle\Repository\TicketRepository") | |
* @Gedmo\SoftDeleteable(fieldName="deletedAt") | |
*/ | |
class Ticket | |
{ | |
use SoftDeleteable; | |
public const TYPE_JURIDICAL = 1; | |
public const TYPE_PHYSICAL = 2; | |
public const TYPES = [ | |
self::TYPE_JURIDICAL => 'JURIDICAL', | |
self::TYPE_PHYSICAL => 'PHYSICAL', | |
]; | |
/** | |
* @var int | |
* | |
* @ORM\Column(name="id", type="integer") | |
* @ORM\Id | |
* @ORM\GeneratedValue(strategy="AUTO") | |
* | |
* @Serializer\Groups({"Ticket", "TicketChat", "post_chats_out", "get_chats_out", "put_chats_out"}) | |
*/ | |
private $id; | |
/** | |
* @var \DateTime | |
* | |
* @ORM\Column(type="datetime") | |
* | |
* @Gedmo\Timestampable(on="create") | |
* | |
* @Serializer\Groups({"Ticket"}) | |
*/ | |
protected $createdAt; | |
/** | |
* @var \DateTime | |
* | |
* @ORM\Column(type="datetime") | |
* | |
* @Gedmo\Timestampable(on="update") | |
* | |
* @Serializer\Groups({"Ticket"}) | |
*/ | |
protected $updatedAt; | |
/** | |
* @var \DateTime | |
* | |
* @ORM\Column(type="datetime", nullable=true) | |
* | |
* @Serializer\Groups({"Ticket"}) | |
*/ | |
protected $closedAt; | |
/** | |
* @var \DateTime | |
* | |
* @ORM\Column(name="deleted_at", type="datetime", nullable=true) | |
*/ | |
protected $deletedAt; | |
/** | |
* @var string | |
* | |
* @ORM\Column(name="subject", type="string", length=255) | |
* | |
* @Serializer\Groups({"Ticket", "post_ticket", "put_ticket", "post_chats_out", "get_chats_out", "put_chats_out"}) | |
* | |
* @Assert\NotBlank | |
* @Assert\Length(max = 255) | |
*/ | |
private $subject; | |
/** | |
* @var string | |
* | |
* @ORM\Column(name="body", type="text", nullable=true) | |
* | |
* @Serializer\Groups({"Ticket", "post_ticket", "put_ticket"}) | |
*/ | |
private $body; | |
/** | |
* @var TicketStatus | |
* | |
* @ORM\ManyToOne(targetEntity="TicketStatus") | |
* @ORM\JoinColumn(name="status_id", referencedColumnName="id", nullable=false) | |
* | |
* @Serializer\Groups({"Ticket", "post_ticket", "put_ticket", "post_chats_out", "get_chats_out", "put_chats_out"}) | |
* @Assert\Type("Ronte\TicketBundle\Entity\TicketStatus") | |
* @Assert\Valid | |
* @Assert\NotNull | |
*/ | |
private $status; | |
/** | |
* @var User | |
* | |
* @ORM\ManyToOne(targetEntity="Ronte\UserBundle\Entity\User") | |
* @ORM\JoinColumn(name="assign_id", referencedColumnName="id", nullable=false) | |
* | |
* @Serializer\Groups({"ChatShort", "post_ticket", "put_ticket"}) | |
* @Assert\Type("Ronte\UserBundle\Entity\User") | |
* @Assert\Valid | |
* @Assert\NotNull | |
*/ | |
private $assign; | |
/** | |
* @var User | |
* | |
* @ORM\ManyToOne(targetEntity="Ronte\UserBundle\Entity\User") | |
* @ORM\JoinColumn(name="client_user_id", referencedColumnName="id", nullable=false) | |
* | |
* @Serializer\Groups({"ChatShort", "post_ticket", "put_ticket"}) | |
* @Assert\Type("Ronte\UserBundle\Entity\User") | |
* @Assert\Valid | |
* @Assert\NotNull | |
*/ | |
private $clientUser; | |
/** | |
* @var User|null | |
* | |
* @ORM\ManyToOne(targetEntity="Ronte\UserBundle\Entity\User") | |
* @ORM\JoinColumn(name="founder_id", referencedColumnName="id", nullable=true) | |
* | |
* @Serializer\Groups({"ChatShort", "post_ticket"}) | |
* @Assert\Type("Ronte\UserBundle\Entity\User") | |
* @Assert\Valid | |
*/ | |
private $founder; | |
/** | |
* @var TicketCategory | |
* | |
* @ORM\ManyToOne(targetEntity="TicketCategory") | |
* @ORM\JoinColumn(name="category_id", referencedColumnName="id", nullable=false) | |
* | |
* @Serializer\Groups({"Ticket", "post_ticket", "put_ticket"}) | |
* | |
* @Assert\Type("Ronte\TicketBundle\Entity\TicketCategory") | |
* @Assert\Valid | |
* @Assert\NotNull | |
*/ | |
private $category; | |
/** | |
* @var int | |
* | |
* @ORM\Column(name="type", type="integer") | |
* | |
* @Serializer\Groups({"Ticket", "post_ticket", "put_ticket"}) | |
* | |
* @Assert\Choice({Ticket::TYPE_PHYSICAL, Ticket::TYPE_JURIDICAL}, strict=true) | |
*/ | |
private $type = self::TYPE_PHYSICAL; | |
/** | |
* @var ArrayCollection | |
* | |
* @ORM\OneToMany(targetEntity="Ronte\TicketBundle\Entity\TicketChat", mappedBy="ticket") | |
*/ | |
protected $ticketChats; | |
/** | |
* Constructor | |
*/ | |
public function __construct() | |
{ | |
$this->ticketChats = new ArrayCollection(); | |
} | |
/** | |
* Get id. | |
* | |
* @return int | |
*/ | |
public function getId() | |
{ | |
return $this->id; | |
} | |
/** | |
* @return \DateTime | |
*/ | |
public function getCreatedAt(): \DateTime | |
{ | |
return $this->createdAt; | |
} | |
/** | |
* @param \DateTime $createdAt | |
* @return Ticket | |
*/ | |
public function setCreatedAt(\DateTime $createdAt): self | |
{ | |
$this->createdAt = $createdAt; | |
return $this; | |
} | |
/** | |
* @return \DateTime | |
*/ | |
public function getUpdatedAt(): \DateTime | |
{ | |
return $this->updatedAt; | |
} | |
/** | |
* @param \DateTime $updatedAt | |
* @return Ticket | |
*/ | |
public function setUpdatedAt(\DateTime $updatedAt): self | |
{ | |
$this->updatedAt = $updatedAt; | |
return $this; | |
} | |
/** | |
* @return \DateTime|null | |
*/ | |
public function getClosedAt(): ?\DateTime | |
{ | |
return $this->closedAt; | |
} | |
/** | |
* @param \DateTime|null $closedAt | |
* @return Ticket | |
*/ | |
public function setClosedAt(\DateTime $closedAt = null): self | |
{ | |
$this->closedAt = $closedAt; | |
return $this; | |
} | |
/** | |
* @param string $subject | |
* @return $this | |
*/ | |
public function setSubject(string $subject): self | |
{ | |
$this->subject = $subject; | |
return $this; | |
} | |
/** | |
* @return string | |
*/ | |
public function getSubject(): string | |
{ | |
return $this->subject; | |
} | |
/** | |
* Set body. | |
* | |
* @param string|null $body | |
* | |
* @return Ticket | |
*/ | |
public function setBody($body = null): self | |
{ | |
$this->body = $body; | |
return $this; | |
} | |
/** | |
* Get body. | |
* | |
* @return string|null | |
*/ | |
public function getBody(): ?string | |
{ | |
return $this->body; | |
} | |
/** | |
* Set status. | |
* | |
* @param TicketStatus $status | |
* | |
* @return Ticket | |
*/ | |
public function setStatus(TicketStatus $status): self | |
{ | |
$this->status = $status; | |
return $this; | |
} | |
/** | |
* Get status. | |
* | |
* @return TicketStatus | |
*/ | |
public function getStatus(): TicketStatus | |
{ | |
return $this->status; | |
} | |
/** | |
* Set assign. | |
* | |
* @param User $assign | |
* | |
* @return Ticket | |
*/ | |
public function setAssign(User $assign): self | |
{ | |
$this->assign = $assign; | |
return $this; | |
} | |
/** | |
* Get assign. | |
* | |
* @return User | |
*/ | |
public function getAssign(): User | |
{ | |
return $this->assign; | |
} | |
/** | |
* Set clientUser. | |
* | |
* @param User $clientUser | |
* | |
* @return Ticket | |
*/ | |
public function setClientUser(User $clientUser): self | |
{ | |
$this->clientUser = $clientUser; | |
return $this; | |
} | |
/** | |
* Get clientUser. | |
* | |
* @return User | |
*/ | |
public function getClientUser(): User | |
{ | |
return $this->clientUser; | |
} | |
/** | |
* Set founder. | |
* | |
* @param User|null $founder | |
* | |
* @return Ticket | |
*/ | |
public function setFounder(User $founder = null): self | |
{ | |
$this->founder = $founder; | |
return $this; | |
} | |
/** | |
* Get founder. | |
* | |
* @return User|null | |
*/ | |
public function getFounder(): ?User | |
{ | |
return $this->founder; | |
} | |
/** | |
* Set category. | |
* | |
* @param TicketCategory $category | |
* | |
* @return Ticket | |
*/ | |
public function setCategory(TicketCategory $category): self | |
{ | |
$this->category = $category; | |
return $this; | |
} | |
/** | |
* Get category. | |
* | |
* @return TicketCategory | |
*/ | |
public function getCategory(): TicketCategory | |
{ | |
return $this->category; | |
} | |
/** | |
* Set type. | |
* | |
* @param int $type | |
* | |
* @return Ticket | |
*/ | |
public function setType(int $type): self | |
{ | |
$this->type = $type; | |
return $this; | |
} | |
/** | |
* Get type. | |
* | |
* @return int | |
*/ | |
public function getType(): int | |
{ | |
return $this->type; | |
} | |
public function getTicketChats(): Collection | |
{ | |
return $this->ticketChats; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment