<?php /** @noinspection PhpUnused */
namespace Roothirsch\CoreBundle\Behaviors\Translatable;
use Doctrine\ORM\EntityManagerInterface;
use Gedmo\Translatable\Entity\Repository\TranslationRepository;
use Gedmo\Translatable\Entity\Translation;
use Roothirsch\CoreBundle\Translation\Repository\LanguageRepository;
use Symfony\Component\Asset\Packages;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\PropertyAccess\PropertyAccess;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\WebpackEncoreBundle\Asset\EntrypointLookupCollectionInterface;
use Symfony\WebpackEncoreBundle\Asset\EntrypointLookupInterface;
class TranslatableFormSubscriber implements EventSubscriberInterface
{
/**
* @var array
*/
protected $locales = [];
/**
* @var string
*/
protected $defaultLocale;
/**
* @var Request
*/
protected $request;
/**
* @var TranslationRepository
*/
protected $translationRepository;
/**
* @var Packages
*/
private $manager;
/**
* @param RequestStack $request
* @param EntityManagerInterface $entityManager
* @param LanguageRepository $languageRepository
*/
public function __construct(RequestStack $request, EntityManagerInterface $entityManager, LanguageRepository $languageRepository, Packages $manager)
{
foreach($languageRepository->findAll() as $language) {
$this->locales[] = $language;
if ($language->isDefaultLanguage() && empty($this->defaultLocale)) {
$this->defaultLocale = $language->getLanguageKey();
}
}
$this->request = $request->getCurrentRequest();
$this->translationRepository = $entityManager->getRepository(Translation::class);
$this->manager = $manager;
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents()
{
return [
FormEvents::PRE_SET_DATA => 'preSetData',
FormEvents::POST_SUBMIT => 'postSubmit',
];
}
/**
* @param FormEvent $event
*/
public function preSetData(FormEvent $event)
{
$form = $event->getForm();
$options = $form->getConfig()->getOptions();
$requiredLocales = $options[TranslatableType::REUIRED_LOCALES];
$entity = $form->getRoot()->getData();
if (empty($entity)) {
return false;
}
$propertyAccessor = PropertyAccess::createPropertyAccessor();
$propertyName = $form->getPropertyPath()->__toString();
$translations = $this->translationRepository->findTranslations($entity);
foreach ($this->locales as $locale) {
if ($locale->isDefaultLanguage()) {
$emptyData = $translations[$locale->getLanguageKey()][$propertyName] ?? $propertyAccessor->getValue($entity, $propertyName);
} else {
$emptyData = $translations[$locale->getLanguageKey()][$propertyName] ?? '';
}
$attribute = $options[TranslatableType::FIELD_OPTIONS]['attr'] ?? [];
$attribute['is_active_tab'] = $locale->getLanguageKey() === $this->defaultLocale;
$attribute['unique'] = uniqid($locale->getLanguageKey());
$attribute['is_bool'] = false;
$attribute['image'] = $this->manager->getUrl('main_theme/media/language_flags/' . $locale->getLanguageKey() . '.png', "main");
if (in_array($options[TranslatableType::TYPE], [CheckboxType::class])) {
$emptyData = boolval($emptyData);
$attribute['is_bool'] = true;
}
$constraints = [];
if (in_array($locale->getLanguageKey(), $requiredLocales)) {
$constraints[] = new NotBlank(['message' => 'Field can\'t be blank!']);
}
$form->add(
$locale->getLanguageKey() . '_content',
$options[TranslatableType::TYPE],
array_merge(
[
'label' => $locale->getLanguageName(),
'data' => $emptyData
],
$options[TranslatableType::FIELD_OPTIONS],
[
'attr' => $attribute
],
['constraints' => $constraints]
)
);
}
}
/**
* @param FormEvent $event
*
* @return false|void
*/
public function postSubmit(FormEvent $event)
{
$form = $event->getForm();
$entity = $form->getRoot()->getData();
if (empty($entity)) {
return false;
}
$propertyName = $form->getPropertyPath()->__toString();
foreach ($this->locales as $locale) {
$data = $form->get($locale->getLanguageKey() . '_content')->getData();
$this->translationRepository->translate($entity, $propertyName, $locale->getLanguageKey(), $data);
}
}
}