<?php
/** @noinspection PhpDocSignatureInspection */
namespace FlexApp\Service;
use Doctrine\ORM\NonUniqueResultException;
use Exception;
use FlexApp\Entity\ChatB;
use FlexApp\Entity\ConsultantEntity;
use FlexApp\Events\Style43\GeneralErrorEvent;
use FlexApp\Repository\ConsultantRepository;
use FlexApp\Repository\CountryAndLangSpecificDataRepository;
use Psr\Cache\InvalidArgumentException;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
use Twig\Environment;
use Twig\Error\LoaderError;
use Twig\Error\RuntimeError;
use Twig\Error\SyntaxError;
use WebBundle\Entity\User;
use WebBundle\Helper\PortalHelper;
use WebBundle\Helper\UserHelper;
use WebBundle\Repository\ListCountryRepository;
use WebBundle\Repository\UserRepository;
class WelcomeInfoDataGenerator
{
const DEFAULT_CONS_PORTAL_LOGIN = 'tkonyukhova';
const DEFAULT_COUNTRY = 'gb';
/**
* @var Environment
*/
private $twig;
/**
* @var PortalHelper
*/
private $portalHelper;
/**
* @var ParametersProvider
*/
private $parametersProvider;
public $welcomeCons;
/**
* @var ListCountryRepository
*/
private $listCountryRepository;
/**
* @var EventDispatcherInterface
*/
private $eventDispatcher;
/**
* @var ConsSchedule
*/
private $consSchedule;
/**
* @var ConsultantRepository
*/
private $consultantRepository;
/**
* @var ConsDefiner
*/
private $consDefiner;
/**
* @var UserRepository
*/
private $userRepository;
/**
* @var TranslatorInterface
*/
private $translator;
/**
* @var AliasByConsLoginProvider
*/
private AliasByConsLoginProvider $aliasByConsLoginProvider;
/** @required */
public TimeFormatTransformer $timeFormatTransformer;
/** @required */
public CountryAndLangSpecificDataRepository $countryAndLangSpecificDataRepository;
public function __construct(
Environment $twig,
PortalHelper $portalHelper,
ParametersProvider $parametersProvider,
ListCountryRepository $listCountryRepository,
EventDispatcherInterface $eventDispatcher,
ConsSchedule $consSchedule,
ConsultantRepository $consultantRepository,
ConsDefiner $consDefiner,
UserRepository $userRepository,
TranslatorInterface $translator,
AliasByConsLoginProvider $aliasByConsLoginProvider
) {
$this->twig = $twig;
$this->portalHelper = $portalHelper;
$this->parametersProvider = $parametersProvider;
$this->listCountryRepository = $listCountryRepository;
$this->consSchedule = $consSchedule;
$this->consultantRepository = $consultantRepository;
$this->consDefiner = $consDefiner;
$this->userRepository = $userRepository;
$this->eventDispatcher = $eventDispatcher;
$this->translator = $translator;
$this->aliasByConsLoginProvider = $aliasByConsLoginProvider;
}
/**
* @return array|string
*
* @throws InvalidArgumentException
* @throws LoaderError
* @throws NonUniqueResultException
* @throws RuntimeError
* @throws SyntaxError
*/
public function generate(ChatB $chat, bool $asHtml = true)
{
/** @var User $user */
$user = $this->userRepository->findOneBy(['token' => $chat->getToken()]);
$cons = $this->consDefiner->getCons(
$chat->getCurrentLocale(),
$chat->getCurrentCountry(),
$user,
UserHelper::getInstance()->getToken()
);
$this->addExtraInfoToSingleLevelConsArray($cons, $chat);
$this->addConsWorkHoursAndWorkDaysAndUTCOffset($cons, $chat);
$translationLang = $this->getTranslationLangForWelcomeMessage($chat);
if ($asHtml) {
return $this->twig->render('ChatB/welcome_info.html.twig', [
'cons' => $cons,
'wiLocale' => $chat->getCurrentLocale(),
'translationLang' => $translationLang,
]);
}
$cons['timezone'] = $this->translator->trans($cons['timezone'], [], null, $chat->getCurrentLocale());
$consultantWord = $this->translator->trans($cons['consWordKey'], [], null, $translationLang);
$discussSchedule = $this->translator->trans('discuss.schedule', [], 'messages',
$chat->getCurrentLocale()) . ' ' . $cons['work_hours'] . " ({$cons['timezone']}). {$cons['work_days']}.";
$discussionHelloOnlineLong = $this->translator->trans('discussion.hello.online.long', [
'%consWord%' => $consultantWord,
'%name%' => $cons['name'],
'%contact_details%' => $cons['contact_details'],
'%work_hours%' => $cons['work_hours'] . ' ' . $cons['timezone'],
], 'messages', $translationLang);
return [
'cons' => $cons,
'trans' => [
'discussSchedule' => $discussSchedule,
'discussionHelloOnlineLong' => $discussionHelloOnlineLong,
],
];
}
/**
* @throws NonUniqueResultException
* @throws Exception
*/
public function addExtraInfoToSingleLevelConsArray(array &$cons, ChatB $chat)
{
$countryString = $chat->getCurrentCountry();
if ('en' === $countryString) {
$countryString = $chat->getCurrentCountryByIp();
if ('en' === $countryString) {
$countryString = self::DEFAULT_COUNTRY;
}
}
$countryEntity = $this->listCountryRepository->getCountry($countryString);
if (null === $countryEntity) {
//TODO нужно добавлять автоматом просьбу на Игоря в этом случае, чтоб он добавил страну
$this->eventDispatcher->dispatch(new GeneralErrorEvent(new Exception("Не удалось найти в БД сущность по стране '{$countryString}' в таблице consultant. Добавьте соответствующую запись в таблицу list_country.")));
$countryEntity = $this->listCountryRepository->getCountry(self::DEFAULT_COUNTRY);
if (!$countryEntity) {//Произойдет, только если из таблицы удалят страну self::DEFAULT_COUNTRY
throw new Exception(sprintf('Не найдена дефолтная страна с кодом %s в таблице list_country. Необходимо добавить эту страну в таблицу list_country в ручном режиме.',
self::DEFAULT_COUNTRY));
}
}
/** @var ConsultantEntity $consultant */
//1. Ищем запись по логину
$consultant = $this->consultantRepository->findOneBy(['portalLogin' => $cons['login']]);
if (!$consultant) {//Если не нашли
//2. Уведомляем, что нет записи с таким логином и добавляем в ручную
$this->eventDispatcher->dispatch(new GeneralErrorEvent(new Exception("Не удалось найти консультанта в БД в таблице consultant для login: '{$cons['login']}'. Необходимо добавить в ручную.")));
//и ищем по дефолтному логину
$consultant = $this->consultantRepository->findOneBy(['portalLogin' => self::DEFAULT_CONS_PORTAL_LOGIN]);
if (!$consultant) {//Если не нашли и по дефолтному
//3. Выкидываем Exception
throw new Exception('Не нашли консультанта в базе данных даже по дефолтному логину');
}
}
$dataEntity = $this->countryAndLangSpecificDataRepository->getDataEntityByCountryAndLang($countryEntity, $chat->getCurrentLocale());
$cons['name'] = $this->aliasByConsLoginProvider->getAlias($cons['login'] ?? '');
$cons['contact_details'] = $consultant->getEmail() . ', ' . $dataEntity->getPhone();
$cons['contact_email'] = $consultant->getEmail();
$cons['contact_phone'] = $dataEntity->getPhone();
$cons['consWordKey'] = $consultant->getSex() ? 'consWordMale' : 'consWordFemale';
$cons['ava'] = "https://img.tile.expert/img_lb/_consults/prew/{$consultant->getAvaFileName()}";
}
/**
* @throws InvalidArgumentException
*/
public function addConsWorkHoursAndWorkDaysAndUTCOffset(array &$cons, ChatB $chat)
{
$schedule = $this->consSchedule->getScheduleByConsLoginAndCountry($cons['login'], $chat->getCurrentCountry(), $chat->getCurrentCountryByIp(),
$chat->getCurrentLocale());
$cons['work_hours'] = $this->timeFormatTransformer->transform($schedule['work_hours_string'], $chat->getCurrentCountry(),
$chat->getCurrentLocale());
$cons['work_days'] = $schedule['work_days_string'];
$cons['timezone'] = $schedule['timezone_string'];
}
private function getTranslationLangForWelcomeMessage(ChatB $chat)
{
if (in_array($chat->getCurrentLocale(), [
'fi',
'sv',
'no'
/*, 'pt'*/
])) { //Для португальского языка просили оставить приветствие на португальском: https://te.remote.team/#/discus/B768BCC7-9553-9FDA-5032-10EE0ED53479/
// https://te.remote.team/#/discus/D306518B-5ECB-65DF-B691-3EF49ADFA0D9
return 'en';
}
return $chat->getCurrentLocale();
}
}