<?php
namespace CioCustomerMailbox\Controller;
use CioCustomerMailbox\Definition\Message\MessageEntity;
use CioCustomerPermissionGroups\Service\CustomerPermissionService;
use CioMasterdata\Definition\Masterdata\MasterdataEntity;
use CioMasterdata\Service\MasterdataService;
use Shopware\Core\Checkout\Cart\Exception\CustomerNotLoggedInException;
use Shopware\Core\Checkout\Customer\CustomerEntity;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\ContainsFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\MultiFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\NotFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\RangeFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Sorting\FieldSorting;
use Shopware\Core\Framework\Struct\ArrayStruct;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Shopware\Storefront\Controller\StorefrontController;
use Shopware\Core\Framework\Routing\Annotation\RouteScope;
use Shopware\Storefront\Page\GenericPageLoader;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
/**
* @RouteScope(scopes={"storefront"})
*/
class MailboxController extends StorefrontController
{
private GenericPageLoader $pageLoader;
private CustomerPermissionService $customerPermissionsService;
/**
* @var EntityRepository
*/
protected EntityRepository $cioMessageRepository;
/**
* @var EntityRepository
*/
protected EntityRepository $cioMessageContentRepository;
protected MasterdataService $masterdataService;
public function __construct(
GenericPageLoader $pageLoader,
CustomerPermissionService $customerPermissionsService,
EntityRepository $cioMessageRepository,
EntityRepository $cioMessageContentRepository,
MasterdataService $masterdataService
)
{
$this->customerPermissionsService = $customerPermissionsService;
$this->pageLoader = $pageLoader;
$this->cioMessageRepository = $cioMessageRepository;
$this->cioMessageContentRepository = $cioMessageContentRepository;
$this->masterdataService = $masterdataService;
}
/**
* @Route("/account/mailbox", name="storefront.account.mailbox.home", methods={"GET"}, defaults={"_routeScope"="storefront"})}}
* @param Request $request
* @param SalesChannelContext $context
* @return Response
*/
public function mailbox(Request $request, SalesChannelContext $context)
{
if (is_null($context->getCustomer())) {
throw new CustomerNotLoggedInException();
}
$page = $this->pageLoader->load($request, $context);
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('customer_id', $context->getCustomer()->getId()));
return $this->renderStorefront('@CioCustomerMailbox/storefront/page/account/mailbox.html.twig', ['page' => $page]);
}
/**
* @Route("/account/mailbox/overview", name="storefront.mailbox.overview", methods={"GET"}, defaults={"_routeScope"="storefront"})}}
* @param Request $request
* @param SalesChannelContext $context
* @return Response
*/
public function overview(Request $request, SalesChannelContext $context)
{
if (is_null($context->getCustomer())) {
throw new CustomerNotLoggedInException();
}
$page = $this->pageLoader->load($request, $context);
/** @var EntityRepository $salesRepresentativeRepository */
$salesRepresentativeRepository = $this->container->get('cio_sales_representative.repository');
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('email', $context->getCustomer()->getEmail()));
$salesRepresentativeId = $salesRepresentativeRepository->searchIds($criteria, $context->getContext())->firstId();
if ($salesRepresentativeId === null) {
throw new NotFoundHttpException();
}
$masterDataCollection = $this->masterdataService->getMasterdasByPartnerId($salesRepresentativeId);
$customers = [];
/** @var MasterdataEntity $masterData */
foreach ($masterDataCollection as $masterData) {
$allCustomers = $this->masterdataService->getCustomersByMasterdataId($masterData->getId(), false);
/** @var CustomerEntity $customer */
foreach ($allCustomers as $customer) {
if (!$customer->getActive()) {
continue;
}
if (array_search($customer->getId(), array_column($customers, 'id')) !== false) {
continue;
}
$customer = $this->getCustomerMessages( $customer, $context, $masterData);
$customers[$customer->getId()] = $customer;
if(is_null($customer->getExtension('customerParent'))) {
$subAccounts = $this->masterdataService->getSubaccounts($customer->getId(), $context->getContext());
foreach ($subAccounts as $subAccount) {
if (!key_exists($subAccount->getId(), $customers)) {
$subAccount = $this->getCustomerMessages( $subAccount, $context, $masterData);
$customers[$subAccount->getId()] = $subAccount;
}
}
}
}
}
return $this->renderStorefront('@CioCustomerMailbox/storefront/page/overview/index.html.twig', ['page' => $page, 'customers' => $customers]);
}
protected function getCustomerMessages(CustomerEntity $customer, SalesChannelContext $context, MasterdataEntity $masterData): CustomerEntity
{
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('customer_id', $customer->getId()));
$criteria->addSorting((new FieldSorting('message_content.number', FieldSorting::DESCENDING)));
$criteria->addFilter(new EqualsFilter('read_at', null));
$criteria->addFilter(new MultiFilter(MultiFilter::CONNECTION_OR, [
new EqualsFilter('message_content.visible_from', null),
new RangeFilter('message_content.visible_from', [
RangeFilter::LTE => (new \DateTime())->setTimezone(new \DateTimeZone('Europe/Berlin'))->format('Y-m-d H:i:s')
])
]));
$criteria->addAssociation('message_content');
$messages = $this->cioMessageRepository->search($criteria, $context->getContext());
$customer->addExtension('runtime', new ArrayStruct([
'messages' => $messages->getEntities()->getElements(),
'countImportantMessages' => $messages->filter(function (MessageEntity $message) {
return $message->getMessageContent()->getImportant() == true;
})->count(),
'countMessages' => $messages->filter(function (MessageEntity $message) {
return $message->getMessageContent()->getImportant() == false;
})->count(),
'vpNumber' => $masterData->getVpNummer()
]));
return $customer;
}
/**
* @Route("/account/mailbox/list", name="storefront.account.mailbox.list", methods={"GET"}, defaults={"_routeScope"="storefront"})}}
* @param Request $request
* @param SalesChannelContext $context
* @return Response
*/
public function list(Request $request, SalesChannelContext $context)
{
if (is_null($context->getCustomer())) {
throw new CustomerNotLoggedInException();
}
$page = $request->query->getInt('page', 1);
$category = $request->query->get('category', 'inbox');
$search = $request->query->get('search');
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('customer_id', $context->getCustomer()->getId()));
$criteria->addSorting((new FieldSorting('message_content.number', FieldSorting::DESCENDING)));
$criteria->setLimit(20);
$criteria->setOffset(($page - 1) * 20);
$criteria->addAssociation('message_content');
if ($category === 'important') {
$criteria->addFilter(new EqualsFilter('message_content.important', 1));
$criteria->addFilter(new EqualsFilter('read_at', null));
} else if ($category === 'read') {
$criteria->addFilter(new NotFilter(NotFilter::CONNECTION_OR, [
new EqualsFilter('read_at', null)
]));
} else if ($category === 'bookmark') {
$criteria->addFilter(new EqualsFilter('bookmark', true));
} else {
$criteria->addFilter(new EqualsFilter('read_at', null));
}
if ($search) {
$criteria->addFilter(new MultiFilter(MultiFilter::CONNECTION_OR, [
new ContainsFilter('message_content.subject', $search),
new ContainsFilter('message_content.content', $search)
]));
}
$criteria->addFilter(new MultiFilter(MultiFilter::CONNECTION_OR, [
new EqualsFilter('message_content.visible_from', null),
new RangeFilter('message_content.visible_from', [
RangeFilter::LTE => (new \DateTime())->setTimezone(new \DateTimeZone('Europe/Berlin'))->format('Y-m-d H:i:s')
])
]));
$messages = $this->cioMessageRepository->search($criteria, $context->getContext());
/** @var EntityRepositoryInterface $mediaRepository */
$mediaRepository = $this->container->get('media.repository');
/** @var MessageEntity $message */
foreach ($messages->getEntities() as $message) {
$shortMessage = html_entity_decode(strip_tags($message->getMessageContent()->getContent()));
$attachmentUrl = null;
if ($attachment = $mediaRepository->search(new Criteria([$message->getMessageContent()->getAttachment()]), $context->getContext())->first()) {
// check if attachment is a pdf
if (strpos($attachment->getMimeType(), 'pdf') !== false) {
$attachmentUrl = $attachment->getUrl();
}
}
$message->addExtension('runtime', new ArrayStruct([
'shortMessage' => substr($shortMessage, 0, 75) . (strlen($shortMessage) > 75 ? '...' : ''),
'attachmentUrl' => $attachmentUrl
]));
}
return $this->json($messages);
}
/**
* @Route("/account/mailbox/list/count", name="storefront.account.mailbox.list.count", methods={"GET"}, defaults={"_routeScope"="storefront"})}}
* @param Request $request
* @param SalesChannelContext $context
* @return Response
*/
public function countMessages(Request $request, SalesChannelContext $context)
{
if (is_null($context->getCustomer())) {
throw new CustomerNotLoggedInException();
}
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('customer_id', $context->getCustomer()->getId()));
$criteria->addFilter(new EqualsFilter('read_at', null));
$criteria->addFilter(new MultiFilter(MultiFilter::CONNECTION_OR, [
new EqualsFilter('message_content.visible_from', null),
new RangeFilter('message_content.visible_from', [
RangeFilter::LTE => (new \DateTime())->setTimezone(new \DateTimeZone('Europe/Berlin'))->format('Y-m-d H:i:s')
])
]));
$inboxCount = $this->cioMessageRepository->search($criteria, $context->getContext())->getTotal();
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('customer_id', $context->getCustomer()->getId()));
$criteria->addFilter(new EqualsFilter('read_at', null));
$criteria->addFilter(new EqualsFilter('message_content.important', 1));
$criteria->addFilter(new MultiFilter(MultiFilter::CONNECTION_OR, [
new EqualsFilter('message_content.visible_from', null),
new RangeFilter('message_content.visible_from', [
RangeFilter::LTE => (new \DateTime())->setTimezone(new \DateTimeZone('Europe/Berlin'))->format('Y-m-d H:i:s')
])
]));
$importantCount = $this->cioMessageRepository->search($criteria, $context->getContext())->getTotal();
return $this->json(['inbox' => $inboxCount, 'important' => $importantCount]);
}
/**
* @Route("/account/mailbox/{id}/markasread", name="storefront.account.mailbox.markasread", methods={"GET"})
* @param Request $request
* @param SalesChannelContext $context
* @return Response
*/
public function markAsRead(Request $request, SalesChannelContext $context)
{
if (is_null($context->getCustomer())) {
throw new CustomerNotLoggedInException();
}
$id = $request->get('id');
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('id', $id));
$criteria->addFilter(new EqualsFilter('customer_id', $context->getCustomer()->getId()));
$message = $this->cioMessageRepository->search($criteria, $context->getContext())->first();
if ($message instanceof MessageEntity) {
$this->cioMessageRepository->update([[
'id' => $id,
'read_at' => new \DateTime()
]], $context->getContext());
return $this->json(['success' => true]);
}
return $this->json(['success' => false]);
}
/**
* @Route("/account/mailbox/{id}/togglebookmark", name="storefront.account.mailbox.togglebookmark", methods={"GET"}, defaults={"_routeScope"="storefront"})}}
* @param Request $request
* @param SalesChannelContext $context
* @return Response
*/
public function toggleBookmark(Request $request, SalesChannelContext $context)
{
if (is_null($context->getCustomer())) {
throw new CustomerNotLoggedInException();
}
$id = $request->get('id');
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('id', $id));
$criteria->addFilter(new EqualsFilter('customer_id', $context->getCustomer()->getId()));
$message = $this->cioMessageRepository->search($criteria, $context->getContext())->first();
if ($message instanceof MessageEntity) {
$this->cioMessageRepository->update([[
'id' => $id,
'bookmark' => !$message->getBookmark()
]], $context->getContext());
return $this->json(['success' => true]);
}
return $this->json(['success' => false]);
}
/**
* @Route("/mailbox/remindlater", name="storefront.mailbox.remindlater", methods={"GET"}, defaults={"_routeScope"="storefront"})}}
* @param Request $request
* @param SalesChannelContext $context
* @return Response
*/
public function remindLater(Request $request, SalesChannelContext $context): Response
{
if (is_null($context->getCustomer())) {
throw new CustomerNotLoggedInException();
}
$request->getSession()->set('mailbox_remind_later', (new \DateTime())->modify('+30 minutes'));
return $this->json(['success' => true]);
}
}