Skip to content

Instantly share code, notes, and snippets.

@zagloo
Last active August 29, 2015 14:22
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save zagloo/1eaedffc2f479686d98f to your computer and use it in GitHub Desktop.
Preflush() "@Orm\PreFlush()" not persisted in Database but return right response to my form
<?php
namespace AVC\MediasBundle\Controller;
use AVC\MediasBundle\Entity\First;
use AVC\MediasBundle\Form\FirstType;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
class TestFirstController extends Controller
{
/**
* @Template("@AVCMedias/test_preflush.html.twig")
* @param Request $request
* @return array
*/
public function testAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
/** @var First $first */
$first = $em->getRepository('AVCMediasBundle:First')->findOneById(1);
$form = $this->createForm(new FirstType(), $first, array());
$form->handleRequest($request);
if ($form->isValid()) {
$em->persist($first);
$em->flush();
$em->clear();
$form = $this->createForm(new FirstType(), $first, array());
}
return array(
'form' => $form->createView(),
);
}
}
<?php
namespace AVC\MediasBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* First
*
* @ORM\Table()
* @ORM\Entity()
* @ORM\HasLifecycleCallbacks()
*/
class First
{
/**
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(name="field1", type="string", length=45, nullable=false)
*/
private $field1;
/**
* @ORM\Column(name="field2", type="string", length=45, nullable=false)
*/
private $field2;
/**
* @ORM\OneToMany(targetEntity="AVC\MediasBundle\Entity\Other", mappedBy="First", orphanRemoval=true, cascade={"all"})
*/
private $Others;
/**
* Constructor
*/
public function __construct()
{
$this->Others = new ArrayCollection();
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set id
*
* @param string $id
* @return First
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
* Get field1
*
* @return string
*/
public function getField1()
{
return $this->field1;
}
/**
* Set field1
*
* @param string $field1
* @return First
*/
public function setField1($field1)
{
$this->field1 = $field1;
return $this;
}
/**
* Get field2
*
* @return string
*/
public function getField2()
{
return $this->field2;
}
/**
* Set field2
*
* @param string $field2
* @return First
*/
public function setField2($field2)
{
$this->field2 = $field2;
return $this;
}
/**
* Add other
*
* @param Other $other
*
* @return First
*/
public function addOther(Other $other)
{
$other->setFirst($this);
$this->Others[] = $other;
return $this;
}
/**
* Remove other
*
* @param Other $other
*/
public function removeOther(Other $other)
{
$this->Others->removeElement($other);
}
/**
* Get others
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getOthers()
{
return $this->Others;
}
/**
* Allow to change the value of "field3" from "Other" Entity when he's Preflushed
* @ORM\PreFlush()
*/
public function testPreFlush()
{
$this->Others->first()->setField3('TEST PREFLUSH');
}
}
<?php
namespace AVC\MediasBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Other
*
* @ORM\Table()
* @ORM\Entity()
* @ORM\HasLifecycleCallbacks()
*/
class Other
{
/**
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(name="field3", type="string", length=45, nullable=false)
*/
private $field3;
/**
* @ORM\Column(name="field4", type="string", length=45, nullable=true)
*/
private $field4;
/**
* @ORM\ManyToOne(targetEntity="AVC\MediasBundle\Entity\First", inversedBy="Others")
*/
private $First;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Get field3
*
* @return string
*/
public function getField3()
{
return $this->field3;
}
/**
* Set field3
*
* @param string $field3
* @return First
*/
public function setField3($field3)
{
$this->field3 = $field3;
return $this;
}
/**
* Get field4
*
* @return string
*/
public function getField4()
{
return $this->field4;
}
/**
* Set field4
*
* @param string $field4
* @return First
*/
public function setField4($field4)
{
$this->field4 = $field4;
return $this;
}
/**
* Get first
*
* @return First
*/
public function getFirst()
{
return $this->First;
}
/**
* Set first
*
* @param First $first
*
* @return Other
*/
public function setFirst(First $first = null)
{
$this->First = $first;
return $this;
}
}
<?php
namespace AVC\MediasBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class FirstType extends AbstractType
{
public function __construct()
{
}
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('field1', 'text', array(
'required' => true,
))
->add('field2', 'text', array(
'required' => true,
))
->add('Others', 'textarea_test', array())
->add('valid', 'submit', array());
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AVC\MediasBundle\Entity\First',
));
}
/**
* @return string
*/
public function getName()
{
return 'avc_mediasbundle_first_test';
}
}
<?php
namespace AVC\MediasBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
/**
* Class OtherType
* @package AVC\MediasBundle\Form
*/
class OtherType extends AbstractType
{
/**
*/
public function __construct()
{
}
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('field3', 'text', array(
'required' => true,
))
->add('field4', 'text', array(
'required' => true,
));
}
/**
* @param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AVC\MediasBundle\Entity\Other',
));
}
/**
* @return string
*/
public function getName()
{
return 'avc_mediasbundle_other_test';
}
}
<?php
namespace AVC\MediasBundle\Form\DataTransformer;
use AVC\MediasBundle\Entity\Other;
use Doctrine\ORM\PersistentCollection;
use DOMDocument;
use DOMElement;
use Symfony\Component\Form\DataTransformerInterface;
/**
* Class TestTransformer
*/
class TestTransformer implements DataTransformerInterface
{
/**
* @var PersistentCollection $PersistentCollection
*/
private $PersistentCollection;
/**
*/
public function __construct()
{
}
/**
* This Transform allows to transform a PersistentCollection into a String
* In this case, I get each value "field3" from "Other" Entity and put each of them into a div with their ID.
* I get a string that seems to : "<div id="1">'value 1 of field3</div> <div id="2">'value 2 of field3</div>..."
* @param PersistentCollection $value
* @return string
*/
public function transform($value)
{
$return = "";
if ($value instanceof PersistentCollection) {
$this->PersistentCollection = $value;
/** @var Other $Other */
$Oters = $value->getValues();
//Put for each value of "field3" from "Other" Entity in a "<div>" tag to get a string "$return" with concatenated "field3"
foreach ($Oters as $Other) {
$return .= '<div id="' . $Other->getId() . '">' . $Other->getField3() . '</div>';
}
}
return $return;
}
/**
* This 'reverseTransform' allows to transform my returned String in a PersistentCollection such as line 35 in my 'transform'
* @param string $value
* @return PersistentCollection
*/
public function reverseTransform($value)
{
if (!empty($value)) {
$dom = new DOMDocument();
$dom->preserveWhiteSpace = false; // Supprime les espaces redondant
$dom->formatOutput = true; // Formate la sortie avec une jolie indentation et des espaces supplémentaires
libxml_use_internal_errors(true); // autorise les balises non conforme html5
$dom->loadHTML('<meta http-equiv="content-type" content="text/html; charset=utf-8">' . $value); // Charge le string $value dans le DOM $dom - La balise "<meta>" Encode en UTF-8 le string $value pour éviter les caractère spéciaux dans la BDD
libxml_use_internal_errors(false); // refuse les balises non conforme html5
$OthersDivs = $dom->getElementsByTagName('div');
/**
* @var DOMElement $OtherDiv
* @var Other $Other
*
*/
$IdOthers = $this->PersistentCollection->map(function ($entity) {
return $entity->getId();
})->toArray();
foreach ($OthersDivs as $OtherDiv) {
$textOtherDiv = $OtherDiv->textContent;
$idOtherDiv = $OtherDiv->getAttribute('id');
if (in_array($idOtherDiv, $IdOthers)) { // Update Entity "Other"
$key = array_search($idOtherDiv, $IdOthers); // Return the key in the PersistentCollection of the Entity "Other"
$Other = $this->PersistentCollection->get($key);
$Other->setField3($textOtherDiv);
unset($IdOthers[$key]);
} else { // Add Entity "Other"
$newOther = new Other();
$newOther->setFirst($this->PersistentCollection->getOwner());
$newOther->setField3($textOtherDiv);
$this->PersistentCollection->add($newOther);
}
}
// Remove Entity "Other"
foreach ($IdOthers as $index => $id) {
$this->PersistentCollection->remove($index);
}
}
return $this->PersistentCollection;
}
}
<?php
namespace AVC\MediasBundle\Form\Type;
use AVC\MediasBundle\Form\DataTransformer\TestTransformer;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class TestType extends AbstractType
{
public function __construct()
{
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$TestTransformer = new TestTransformer();
$builder->addModelTransformer($TestTransformer);
}
public function configureOptions(OptionsResolver $resolver)
{
}
public function getParent()
{
return 'textarea';
}
public function getName()
{
return 'textarea_test';
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment