<?php
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
namespace App\Controller;
use Symfony\Component\HttpFoundation\Response;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use App\Entity\OriginalDictionary;
use App\Entity\TranslationDictionary;
use App\Entity\DocumentDictionary;
use Twig\Environment;
use App\Service\utiltranslate;
use Doctrine\ORM\EntityManagerInterface;
/**
* Controlador que renderiza el template para editar y guarda los datos editados
*
* @author arodriguez
*/
class EditController extends AbstractController
{
private $twig;
private $utiltranslate;
private $em;
public function __construct(EntityManagerInterface $em,Environment $twig,utiltranslate $utiltranslate)
{
$this->em = $em;
$this->twig = $twig;
$this->utiltranslate= $utiltranslate;
}
/* Calcula el id del siguiente elemento mostrado en el grid*/
private function siguiente($id, $length)
{
$position = array_search($id, $_SESSION['ids']);
if($position === $length-1) return null;
else return $_SESSION['ids'][++$position];
}
/* Calcula el id del elemento anterior mostrado en el grid*/
private function anterior($id)
{
$position = array_search($id, $_SESSION['ids']);
if($position == 0) return null;
else return $_SESSION['ids'][--$position];
}
/**
* Comprueba si el docuemnto está listo en un idioma en concreto para
* enviar el mail al creador del mismo. Se comprueba también la cantidad de
* idiomas que han completado la traducción para indicarlo en el correo
* @param type $documents
* @param type $langTraduccion
*/
private function checkDocuments($documents,$langTraduccion)
{
foreach($documents as $document)
{
$id = $document->getId();
$completados=0;
//Obtenemos los idiomas que hay en cada documento.
$langsOfDocument = $this->em->getRepository(DocumentDictionary::class)->getLangsOfDocument();
$total = count($langsOfDocument);
$send = false;
foreach ($langsOfDocument as $lang){
$result = $this->utiltranslate->getPending($id,$lang);
$auxcompletados = $completados;
//Si quedan pendientes, no está listo el documento aún.
if($result) $completados += 0;
else $completados +=1;
if(($langTraduccion===$lang)&&($auxcompletados!==$completados)){
$send=true;
}
}
if (($send)&&($completados>0)){
$this->utiltranslate->sendLanguageReady($document, $langTraduccion, $total, $completados);
}
}
}
private function sendReview($originalText, $previous, $documents)
{
//Obtenemos los creadores distintos asociados a los documentos que han sido afectados por la modificación.
$creators= array();
$documentos = "";
$isWebError= false;
foreach ($documents as $document)
{
$project = $document->getProject();
if($project->getName()=="Web") {$isWebError = true;}
$temp = $document->getCreator();
if (!in_array($temp, $creators)) {$creators[]=$temp;}
$documentos.= $document->getName().", ";
}
//Manda el correo a cada creador.
$message = \Swift_Message::newInstance()
->setSubject("Un texto en castellano ha sido modificado")
->setFrom('webmaster@visiotechsecurity.com');
foreach ($creators as $user)
{
$message->setTo($user->getEmail())
->setBody("Se ha cambiado de: \n".$previous."\n"
. " a: \n".$originalText.
".\n\n Esto afecta a los siguientes documentos: \n".$documentos);
$respuesta = $this->get('mailer')->send($message);
// $this->mailer->send($message);
}
//Si se ha prpoducido un error en un documento de la web se notifica a producto para que cambie la ficha.
if($isWebError)
{
$message->setTo("producto@visiotechsecurity.com")
->setBody("Se ha cambiado de: \n".$previous."\n"
. " a: \n".$originalText.
".\n\n Esto afecta a los productos siguientes: \n".$documentos);
$respuesta = $this->get('mailer')->send($message);
}
return new Response("Mensaje enviado");
}
private function modifyBaseText($originalText, $previous, $documents)
{
foreach($documents as $document)
{
$baseText = $document->getBaseText();
$replace=str_replace($previous,$originalText, $baseText);
$document->setBaseText($replace);
//$baseText = $document->getBaseText();
}
}
private function setReview($original, $lang)
{
$em =$this->getDoctrine()->getManager();
$translations= $original->getTranslations()->toArray();
$emTranslation=$em->getRepository(TranslationDictionary::class);
$currentLangs = $emTranslation->getLanguagesOfOriginal($original);
foreach($translations as $translation)
{
if ($lang!==$translation->getLang())
{
$translation->setStatus("review");
}
}
}
/**
* @Route("/jtext" , name = "controlJtext")
* @Template("dictionary/edit.html.twig")
* Realiza la búsqueda del texto a traducir y muestra su información en la vista para editarlo
*/
public function controlJtext(){
return $this->render('dictionary/jtext.html.twig');
}
/**
* @Route("/translations/edit/{id}/{lang}" , name = "showEditData")
* @Template("dictionary/edit.html.twig")
* Realiza la búsqueda del texto a traducir y muestra su información en la vista para editarlo
*/
public function showEditAction($id =0, $lang ="en")
{
//obtenemos la traducción de la base de datos
$em =$this->getDoctrine()->getManager();
$row = $em->getRepository(TranslationDictionary::class)->find($id);
if (!$row)
{
throw $this->createNotFoundException
(
'No translation found for id '.$id
);
}
//cogemos los documentos y los proyectos asociados a la traduccion.
list($project,$document)=$this->utiltranslate->getProjectsyDocumentsOfTranslation($id);
//cogemos el texto original y el texto de la traducción.
$original = $row->getOriginal();
$originalText = $original->getOriginal();
$translationText = $row->getTranslation();
//Cogemos todos los documentos y proyectos asociados.
list($documents,$projects)=$this->utiltranslate->getProjectsyDocuments();
//Si está en review mostramos el texto que había antes.
if($row->getStatus()==="review") $previous = $original->getPrevious();
else $previous = "";
//Con los ids en sesión calculamos los ids de las traducciones anterior y siguiente. 0 si no hay traducción.
if(isset($_SESSION['ids']))
{
$length = count($_SESSION['ids']);
$siguiente = $this->siguiente($id , $length);
$anterior = $this->anterior($id);
}
else
{
$siguiente=0;
$anterior=0;
}
return array
(
'id' => $id,
'lang' => $lang,
'original' => $originalText,
'translation' => $translationText,
'documents'=> $documents,
'document'=>$document,
'projects'=> $projects,
'project'=>$project,
'siguiente' => $siguiente,
'anterior' => $anterior,
'previous' => $previous,
);
}
/**
* @Route("/translations/editSucces/{id}/{lang}/" , name = "editData")
* @param type $id
* @param type $lang
* Modifica en la base de datos lo introducido en el template edit.html.twig
* obteniendo la informacion mediante POST recogido en el formulario de la vista.
*/
public function editAction($id, $lang)
{
$id = intval($id);
$em =$this->getDoctrine()->getManager();
//Recogemos el texto introducido como traducción.
if (isset($_POST["translation"]))
{
$nTranslation = trim($_POST["translation"]);
$isHTML= filter_var($_POST["ishtml"], FILTER_VALIDATE_BOOLEAN);
if(!$isHTML)
{
$nTranslation = strip_tags($nTranslation);
$evilStrings=array("[% VAR%]","[% VAR %]","[%VAR %]","[%var%]","[%DAR%]");
$nTranslation = str_replace($evilStrings, "[%VAR%]", $nTranslation);
}
$nTranslation = str_replace(" "," ", $nTranslation);
}
//Recuperamos el objeto traducción a partir del id.
$translation = $em->getRepository(TranslationDictionary::class)->find($id);
if (!$translation)
{
throw $this->createNotFoundException(
'No translation found for id '.$id
);
}
//Obtenemos el objeto original
$original = $translation->getOriginal();
$check = false;
//si guardamos algo que está en review pasa a ready.
if($translation->getStatus()==="review")
{
$translation->setStatus("ready");
$check = true;
}
$hashNueva = hash('md5',$nTranslation);
if (isset($_POST["copyCheck"]))
{
//Si se ha marcado copyCheck guardamos la misma traduccion en todos los idiomas y marcamos fixed
$original->setFixed(true);
$this->copyTranslations($original,$nTranslation,$hashNueva,$em);
$check = true;
}
else
{
//Mediante hash comprobamos que se haya modificado la traduccion y la guardamos
$hashTranslation = $translation->getHash();
if($hashTranslation!== $hashNueva)
{
$translation->setTranslation($nTranslation);
$translation->setHash($hashNueva);
$check = true;
}
}
$translation->setModified(new \DateTime());
$documents= $translation->getDocuments();
//Si se ha editado el texto original...
if (isset($_POST["original"]))
{
$nOriginal= trim(htmlspecialchars($_POST["original"]));
//Comprobamos si realmente se ha modificado, en ese caso, lo guardamos
$hashOriginal = $original->getHash();
$hashNuevoOriginal = hash('md5', $nOriginal);
if($hashNuevoOriginal !== $hashOriginal)
{
$original -> setOriginal($nOriginal);
$original -> setHash($hashNuevoOriginal);
//ponemos en review las traducciones en el resto de idiomas.
$this->setReview($original,$lang);
$this->setReview($original,$lang);
$this->modifyBaseText($original->getOriginal(),$original->getPrevious(),$documents);
//Mandamos un correo a los creadores de los documentos indicando que se ha modificado el original.
$this->sendReview($original->getOriginal(), $original->getPrevious(),$documents);
}
}
$em->flush();
//deshabilitamos las notificaciones a documentos porque el cruce de documentos lo tiene a la tabla vieja de usuarios. Hay que actualizarlos a la tabla nueva de
// if ($check){
// $this->checkDocuments($documents,$lang);
// }
if (isset($_POST["move"])){
$move= $_POST["move"];
//cogemos el id de la traducción siguiente.
if ($move==="siguiente") $id = $this->siguiente ($id, count($_SESSION['ids']));
//cogemos el anterior si se ha puldado la flecha hacia atras.
else if($move==="anterior") $id = $this->anterior($id);
// Si damos a guardar, volvemos al grid habiendo guardado los cambios.
else return $this->redirect($this->generateUrl('showTranslationsGrid', array('lang' => $lang)),301 );
return $this->redirect ($this->generateUrl ('showEditData', array('id' =>$id, 'lang' =>$lang)), 301);
}
return $this->redirect($this->generateUrl('showTranslationsGrid', array('lang' => $lang)),301 );
}
/**
*
* @param type $original DictionaryOriginal sobre el que sacar las traduccioness
* @param type $nTranslation texto a guardar
* @param type $hashNueva hash del texto a almacenar
* @param type $em manager de doctrine
* Funcion utilizada para copiar el texto de la traducción a todos los idiomas
* cuando el texto sea fijo
*/
private function copyTranslations($original,$nTranslation,$hashNueva)
{
$translations = $original->getTranslations();
if($translations)
{ //Copiamos el texto a las traducciones existentes.
foreach($translations as $translation)
{
$translation->setTranslation($nTranslation);
$translation->setHash($hashNueva);
}
}
}
}