<?php
namespace Atiweb\EventSubscriber;
use App\Entity\Www\Textes;
use Atiweb\Form\TextareaTransType;
use Atiweb\Form\TextTransType;
use Atiweb\Form\TinyMceTransType;
use Atiweb\Form\TinyMceType;
use Atiweb\Translation\Translation;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
/**
* Class TransSubscriber
* @package Atiweb\Translation
*/
class TransSubscriber implements EventSubscriberInterface
{
private $_locales;
private $_translationService;
private $arrayKeyTrans = [];
private $em;
private $translationEntities = [];
/**
* TransSubscriber constructor.
* @param Translation $translationService
* @param array $locales
* @param EntityManagerInterface $em
*/
public function __construct(
Translation $translationService,
array $locales,
EntityManagerInterface $em
) {
$this->_translationService = $translationService;
$this->_locales = $locales;
$this->em = $em;
}
/**
* @param $property
* @param $keyTrans
*/
public function setKeyTrans($property, $keyTrans) {
$this->arrayKeyTrans[$property] = $keyTrans;
}
/**
* @param $property
* @param Textes $translationEntity
*/
public function setTranslationEntity($property, Textes $translationEntity) {
$this->translationEntities[$property] = $translationEntity;
}
/**
* @return string[]
*/
public static function getSubscribedEvents()
{
return [
FormEvents::PRE_SET_DATA => 'preSetData',
FormEvents::POST_SUBMIT => 'postSubmit',
];
}
/**
* @param FormEvent $event
*/
public function preSetData(FormEvent $event)
{
if($event->getData()) {
$form = $event->getForm();
foreach ($form as $propertyName => $propertyInfo) {
$isTrans = $this->_translationService->isTrans($event->getData(), $propertyName);
if ($isTrans and !array_key_exists($propertyName, $this->arrayKeyTrans)) {
if($propertyInfo->getConfig()->getOption("locale") !== null) {
continue;
}
$this->setKeyTrans($propertyName, $event->getData()->{'get' . ucfirst($propertyName)}());
$translationEntity = $event->getData()->{'get' . ucfirst($propertyName)}();
if(
$propertyInfo->getConfig()->getType()->getInnerType() instanceof TextareaTransType
or $propertyInfo->getConfig()->getType()->getInnerType() instanceof TextareaType
) {
$entryType = TextareaTransType::class;
} else if (
$propertyInfo->getConfig()->getType()->getInnerType() instanceof TinyMceType
or $propertyInfo->getConfig()->getType()->getInnerType() instanceof TinyMceTransType
) {
$entryType = TinyMceTransType::class;
}
else {
$entryType = TextTransType::class;
}
$data = [];
// WYSIWYG options
$options = [];
if(null !== $form->get($propertyName)->getConfig()->getAttribute('data_collector/passed_options')['config_name']) {
$options["config_name"] = $form->get($propertyName)->getConfig()->getAttribute('data_collector/passed_options')['config_name'];
}
if(null !== $form->get($propertyName)->getConfig()->getAttribute('data_collector/passed_options')['config']) {
$options["config"] = $form->get($propertyName)->getConfig()->getAttribute('data_collector/passed_options')['config'];
}
if(null !== $form->get($propertyName)->getConfig()->getAttribute('data_collector/passed_options')['attr']) {
$options["attr"] = $form->get($propertyName)->getConfig()->getAttribute('data_collector/passed_options')['attr'];
}
foreach ($this->_locales as $lang) {
if($lang === 'fr') { // Needed (mapped:false) to move field to translation:field
$form->add($propertyName, $entryType, array_merge([
'data' => $translationEntity ? $translationEntity->{'get' . ucfirst($lang)}() : '',
'mapped' => false,
'constraints' => $form->get($propertyName)->getConfig()->getAttribute('data_collector/passed_options')['constraints'],
'required' => $form->get($propertyName)->getConfig()->getAttribute('data_collector/passed_options')['required'],
], $options));
} else {
$data[] = $translationEntity ? $translationEntity->{'get' . ucfirst($lang)}() : '';
}
}
$form->add($propertyName . '_translation', CollectionType::class, [
'entry_type' => $entryType,
'data' => $data,
'mapped' => false,
'required' => false,
'constraints' => [], // TODO: send param if legacy constaints about realField
]);
}
}
}
}
/**
* @param FormEvent $event
* @return null
*/
public function postSubmit(FormEvent $event) // Is called for each field !!!
{
foreach($this->arrayKeyTrans as $propertyKeyTrans => $valueKeyTrans) {
$form = $event->getForm();
if ($form and ($form->getName() == $propertyKeyTrans or $form->getName() == ($propertyKeyTrans . '_translation'))) {
$realFieldName = str_replace('_translation', '', $form->getName());
if(array_key_exists($realFieldName, $this->translationEntities)) {
$translationEntity = $this->translationEntities[$realFieldName];
}
else {
if($valueKeyTrans == '') {
$translationEntity = new Textes();
} else {
$translationEntity = $valueKeyTrans ?? new Textes();
}
$this->em->persist($translationEntity); // Not needed if field => cascade={"persist"}
$this->setTranslationEntity($propertyKeyTrans, $translationEntity);
}
if($form->getName() == $propertyKeyTrans) { // If current = untranslatable field
$translationEntity->setFr($form->getData() ?? '');
try {
$event->getForm()->getParent()->getData()->{'set' . ucfirst($propertyKeyTrans)}($translationEntity);
} catch (\Error $e) {
return null;
}
} else {
$loop = 0;
foreach ($this->_locales as $k => $lang) {
if($lang !== 'fr') {
$translationEntity->{'set' . $lang}($form->getData()[$loop] ?? '');
$loop++;
}
}
}
}
}
}
}