CustomField : JSON -> OBJECT DANS ENTITY

This commit is contained in:
Marc Ducobu 2014-10-13 08:44:20 +02:00
parent f624bce689
commit cd2a7bff53
11 changed files with 752 additions and 0 deletions

View File

@ -0,0 +1,226 @@
<?php
namespace CL\CustomFieldsBundle\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use CL\CustomFieldsBundle\Entity\BlopEntity2;
use CL\CustomFieldsBundle\Form\BlopEntity2Type;
/**
* BlopEntity2 controller.
*
*/
class BlopEntity2Controller extends Controller
{
/**
* Lists all BlopEntity2 entities.
*
*/
public function indexAction()
{
$em = $this->getDoctrine()->getManager();
$entities = $em->getRepository('CLCustomFieldsBundle:BlopEntity2')->findAll();
return $this->render('CLCustomFieldsBundle:BlopEntity2:index.html.twig', array(
'entities' => $entities,
));
}
/**
* Creates a new BlopEntity2 entity.
*
*/
public function createAction(Request $request)
{
$entity = new BlopEntity2();
$form = $this->createCreateForm($entity);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('blopentity2_show', array('id' => $entity->getId())));
}
return $this->render('CLCustomFieldsBundle:BlopEntity2:new.html.twig', array(
'entity' => $entity,
'form' => $form->createView(),
));
}
/**
* Creates a form to create a BlopEntity2 entity.
*
* @param BlopEntity2 $entity The entity
*
* @return \Symfony\Component\Form\Form The form
*/
private function createCreateForm(BlopEntity2 $entity)
{
$form = $this->createForm(new BlopEntity2Type(), $entity, array(
'action' => $this->generateUrl('blopentity2_create'),
'method' => 'POST',
'em' => $this->getDoctrine()->getManager(),
));
$form->add('submit', 'submit', array('label' => 'Create'));
return $form;
}
/**
* Displays a form to create a new BlopEntity2 entity.
*
*/
public function newAction()
{
$entity = new BlopEntity2();
$form = $this->createCreateForm($entity);
return $this->render('CLCustomFieldsBundle:BlopEntity2:new.html.twig', array(
'entity' => $entity,
'form' => $form->createView(),
));
}
/**
* Finds and displays a BlopEntity2 entity.
*
*/
public function showAction($id)
{
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('CLCustomFieldsBundle:BlopEntity2')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find BlopEntity2 entity.');
}
$deleteForm = $this->createDeleteForm($id);
return $this->render('CLCustomFieldsBundle:BlopEntity2:show.html.twig', array(
'entity' => $entity,
'delete_form' => $deleteForm->createView(),
));
}
/**
* Displays a form to edit an existing BlopEntity2 entity.
*
*/
public function editAction($id)
{
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('CLCustomFieldsBundle:BlopEntity2')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find BlopEntity2 entity.');
}
$editForm = $this->createEditForm($entity);
$deleteForm = $this->createDeleteForm($id);
return $this->render('CLCustomFieldsBundle:BlopEntity2:edit.html.twig', array(
'entity' => $entity,
'edit_form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),
));
}
/**
* Creates a form to edit a BlopEntity2 entity.
*
* @param BlopEntity2 $entity The entity
*
* @return \Symfony\Component\Form\Form The form
*/
private function createEditForm(BlopEntity2 $entity)
{
$form = $this->createForm(new BlopEntity2Type(), $entity, array(
'action' => $this->generateUrl('blopentity2_update', array('id' => $entity->getId())),
'method' => 'PUT',
'em' => $this->getDoctrine()->getManager(),
));
$form->add('submit', 'submit', array('label' => 'Update'));
return $form;
}
/**
* Edits an existing BlopEntity2 entity.
*
*/
public function updateAction(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('CLCustomFieldsBundle:BlopEntity2')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find BlopEntity2 entity.');
}
$deleteForm = $this->createDeleteForm($id);
$editForm = $this->createEditForm($entity);
$editForm->handleRequest($request);
if ($editForm->isValid()) {
$em->flush();
return $this->redirect($this->generateUrl('blopentity2_edit', array('id' => $id)));
}
return $this->render('CLCustomFieldsBundle:BlopEntity2:edit.html.twig', array(
'entity' => $entity,
'edit_form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),
));
}
/**
* Deletes a BlopEntity2 entity.
*
*/
public function deleteAction(Request $request, $id)
{
$form = $this->createDeleteForm($id);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('CLCustomFieldsBundle:BlopEntity2')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find BlopEntity2 entity.');
}
$em->remove($entity);
$em->flush();
}
return $this->redirect($this->generateUrl('blopentity2'));
}
/**
* Creates a form to delete a BlopEntity2 entity by id.
*
* @param mixed $id The entity id
*
* @return \Symfony\Component\Form\Form The form
*/
private function createDeleteForm($id)
{
return $this->createFormBuilder()
->setAction($this->generateUrl('blopentity2_delete', array('id' => $id)))
->setMethod('DELETE')
->add('submit', 'submit', array('label' => 'Delete'))
->getForm()
;
}
}

View File

@ -0,0 +1,248 @@
<?php
namespace CL\CustomFieldsBundle\Entity;
use Doctrine\ORM\EntityManager;
use Doctrine\Common\Persistence\Event\LifecycleEventArgs;
use Doctrine\ORM\Event\PreFlushEventArgs;
use Doctrine\Common\Collections\ArrayCollection;
use CL\CustomFieldsBundle\Entity\Adress;
// ATTENTION QD NOUVEL OBJ cree sans appel a doctrine
// on n'a pas la config de custom fields
// ET DONC ON NE SAIT PAS QUELS VARIABLES SONT VIA __GET
// ET __SET SONT DECRITES PAR CUSTOM FIELDS
// IDEE : Travailler avec Lifecycle
// set et get pour JSON Field
// - dans un tableau special
// postLoad (après que l'élément sort du EM) :
// - récupération des customs fields (ok!)
// - json -> obj dans des choses qui existent deja
// preFlush avant mise a jour de la db
// - met a jour les donnees liees au json et le json
// perPersist idem mais pour le persist
/**
* BlopEntity2
*/
class BlopEntity2
{
/**
* @var integer
*/
private $id;
/**
* @var array
*/
private $customFieldData;
private $customFieldDataArray = array(); // customField apres json_decode
private $customFieldDataUnfolded = array(); // mise des entity de customFieldDataArray
private $customFieldConfigs = array();
private $customFieldConfigsLoaded = false;
// CHARGE DE LA DB LA CONFIG DES CUSTOM FIELDS
public function loadCustomFieldConfig(LifecycleEventArgs $args)
{
$em = $args->getObjectManager();
$customFields = $em
->getRepository('CLCustomFieldsBundle:CustomField')
->findAll();
$customFieldsLablels = array_map(
function($e) { return $e->getLabel(); },
$customFields);
$this->customFieldConfigs = array_combine($customFieldsLablels, $customFields);
$this->customFieldConfigsLoaded = true;
}
// A PARTIR DU JSON CREE LES OBJETS (MIS DANS customFieldDataUnfolded)
public function unfoldCustomFieldData(LifecycleEventArgs $args)
{
$em = $args->getObjectManager();
$customFieldDataArray = json_decode($this->customFieldData,true);
$customFieldDataUnfolded = array();
foreach ($this->customFieldConfigs as $key => $cfConfig) {
$type = $cfConfig->getType();
if(strpos($type,'ManyToMany') === 0) {
$fieldUnfolded = new ArrayCollection();
if(array_key_exists($key, $customFieldDataArray)) {
$entityClass = substr($type, 11, -1);
foreach ($customFieldDataArray[$key] as $idEntity) {
$fieldUnfolded->add($em
->getRepository('CLCustomFieldsBundle:' . $entityClass)
->findOneById($idEntity));
}
}
$customFieldDataUnfolded[$key] = $fieldUnfolded;
} else if(strpos($type,'ManyToOne') === 0) {
$entityClass = 'Adress'; // substr($type,10,-1);
if(array_key_exists($key, $customFieldDataArray)) {
$customFieldDataUnfolded[$key] = $em
->getRepository('CLCustomFieldsBundle:' . $entityClass)
->findOneById($customFieldDataArray[$key]);
} else {
// TODO : doit tjs avoir un id
$em
->getRepository('CLCustomFieldsBundle:' . $entityClass)
->findOneById(1);
}
}
else if ($type === 'text') {
if(array_key_exists($key, $customFieldDataArray)) {
$customFieldDataUnfolded[$key] = $customFieldDataArray[$key];
} else {
$customFieldDataUnfolded[$key] = '';
}
}
}
$this->customFieldDataUnfolded = $customFieldDataUnfolded;
}
// AVANT PERSIST LES ELEMENTS QUI N'ONT PAS D'ID DOIVENT EN AVOIR UN (OM->PERSIST(OBJ))
// PUIS PASSAGE DES OBJETS (SE TROUVANT DANS customFieldDataUnfolded) VERS
// LE JSON (SE TROUVANT DANS customFieldData)
public function prePersist(LifecycleEventArgs $args)
{
$em = $args->getObjectManager();
$this->loadCustomFieldConfig($args);
foreach ($this->customFieldDataUnfolded as $key => $unfoldedData) {
$type = $this->customFieldConfigs[$key]->getType();
if(strpos($type,'ManyToMany') === 0) {
foreach ($this->customFieldDataUnfolded[$key] as $entity) {
if(! $entity->getId()) {
$em->persist($entity);
}
}
} else if(strpos($type,'ManyToOne') === 0) {
if(! $this->customFieldDataUnfolded[$key]->getId()) {
$em->persist($this->customFieldDataUnfolded[$key]);
}
}
}
$this->customFieldDataUnfoldedToCustomField();
}
// PUIS PASSAGE DES OBJETS (SE TROUVANT DANS customFieldDataUnfolded) VERS
// LE JSON (SE TROUVANT DANS customFieldData)
public function preFlush(PreFlushEventArgs $args)
{
$this->customFieldDataUnfoldedToCustomField();
}
// PUIS PASSAGE DES OBJETS (SE TROUVANT DANS customFieldDataUnfolded) VERS
// LE JSON (SE TROUVANT DANS customFieldData)
public function customFieldDataUnfoldedToCustomField()
{
// MISE A JOUR DE customFieldDataArray
foreach ($this->customFieldConfigs as $key => $cfConfig) {
$type = $cfConfig->getType();
if(strpos($type,'ManyToMany') === 0) {
$arrayMapRet = array();
foreach ($this->customFieldDataUnfolded[$key] as $entity) {
$arrayMapRet[] = $entity->getId();
}
$this->customFieldDataArray[$key] = $arrayMapRet; // array_map(function($e) { $e->getId(); }, $this->customFieldDataUnfolded[$key]);
} else if(strpos($type,'ManyToOne') === 0) {
if(array_key_exists($key, $this->customFieldDataUnfolded)) {
$this->customFieldDataArray[$key] = $this->customFieldDataUnfolded[$key]->getId();
} else {
// normalement $this->customFieldDataArray[$key] ne doit pas exister
if(array_key_exists($key, $this->customFieldDataArray)) {
throw new Exception("Error Processing Request", 1);
}
//retirer de $this->customFieldDataArray[$key]
}
} else if ($type === 'text') {
$this->customFieldDataArray[$key] = $this->customFieldDataUnfolded[$key];
}
}
// MISE A JOUR DE CustomFieldData
$this->setCustomFieldData(json_encode($this->customFieldDataArray));
}
public function __set($fieldName, $value) {
$setMethodName = 'set' . ucfirst($fieldName);
if(method_exists($this, $setMethodName)) {
return $this->{$setMethodName}($value);
}
if(array_key_exists($fieldName, $this->customFieldConfigs)) {
$this->customFieldDataUnfolded[$fieldName] = $value;
} else if (!$this->customFieldConfigsLoaded) { // nouvel object pas eu d'appel doctrine avant
$this->customFieldDataUnfolded[$fieldName] = $value;
} else {
throw new Exception("Error Processing Request", 1);
}
}
public function __get($fieldName) {
$getMethodName = 'get' . ucfirst($fieldName);
if(method_exists($this, $getMethodName)) {
return $this->{$getMethodName}();
}
if(array_key_exists($fieldName, $this->customFieldDataUnfolded)) {
return $this->customFieldDataUnfolded[$fieldName];
} else if (!$this->customFieldConfigsLoaded) { // nouvel object pas eu d'appel doctrine avant
return null;
} else if(array_key_exists($fieldName, $this->customFieldConfigs)) { // pas init
return null;
} else {
throw new Exception("Error Processing Request", 1);
}
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set customField
*
* @param array $customField
*
* @return BlopEntity2
*/
public function setCustomFieldData($customFieldData)
{
$this->customFieldData = $customFieldData;
return $this;
}
/**
* Get customField
*
* @return array
*/
public function getCustomFieldData()
{
return $this->customFieldData;
}
}

View File

@ -0,0 +1,69 @@
<?php
namespace CL\CustomFieldsBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class BlopEntity2Type extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$em = $options['em'];
$customFields = $em
->getRepository('CLCustomFieldsBundle:CustomField')
->findAll();
foreach ($customFields as $cf) {
if($cf->getType() === 'ManyToOne(Adress)') {
$builder->add($cf->getLabel(), 'entity', array(
'class' => 'CLCustomFieldsBundle:Adress',
'property' => 'data'
));
} else if ($cf->getType() === 'ManyToOnePersist(Adress)') {
$builder->add($cf->getLabel(), new AdressType());
} else if($cf->getType() === 'ManyToMany(Adress)') {
$builder->add($cf->getLabel(), 'entity', array(
'class' => 'CLCustomFieldsBundle:Adress',
'property' => 'data',
'multiple' => true
));
} else if ($cf->getType() === 'text') {
$builder->add($cf->getLabel(), 'text');
}
}
}
/**
* @param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'CL\CustomFieldsBundle\Entity\BlopEntity2'
));
// supprimer ça en definissant dans services
$resolver->setRequired(array(
'em',
));
$resolver->setAllowedTypes(array(
'em' => 'Doctrine\Common\Persistence\ObjectManager',
));
}
/**
* @return string
*/
public function getName()
{
return 'cl_customfieldsbundle_blopentity2';
}
}

View File

@ -0,0 +1,16 @@
CL\CustomFieldsBundle\Entity\BlopEntity2:
type: entity
table: null
id:
id:
type: integer
id: true
generator:
strategy: AUTO
fields:
customFieldData:
type: json_array
lifecycleCallbacks:
postLoad: [ loadCustomFieldConfig, unfoldCustomFieldData ]
preFlush: [ preFlush ]
prePersist: [ prePersist ]

View File

@ -1,3 +1,7 @@
cl_custom_fields_blopentity2:
resource: "@CLCustomFieldsBundle/Resources/config/routing/blopentity2.yml"
prefix: /blopentity2
cl_custom_fields_adress: cl_custom_fields_adress:
resource: "@CLCustomFieldsBundle/Resources/config/routing/adress.yml" resource: "@CLCustomFieldsBundle/Resources/config/routing/adress.yml"
prefix: /adress prefix: /adress

View File

@ -0,0 +1,30 @@
blopentity2:
path: /
defaults: { _controller: "CLCustomFieldsBundle:BlopEntity2:index" }
blopentity2_show:
path: /{id}/show
defaults: { _controller: "CLCustomFieldsBundle:BlopEntity2:show" }
blopentity2_new:
path: /new
defaults: { _controller: "CLCustomFieldsBundle:BlopEntity2:new" }
blopentity2_create:
path: /create
defaults: { _controller: "CLCustomFieldsBundle:BlopEntity2:create" }
requirements: { _method: post }
blopentity2_edit:
path: /{id}/edit
defaults: { _controller: "CLCustomFieldsBundle:BlopEntity2:edit" }
blopentity2_update:
path: /{id}/update
defaults: { _controller: "CLCustomFieldsBundle:BlopEntity2:update" }
requirements: { _method: post|put }
blopentity2_delete:
path: /{id}/delete
defaults: { _controller: "CLCustomFieldsBundle:BlopEntity2:delete" }
requirements: { _method: post|delete }

View File

@ -0,0 +1,16 @@
{% extends '::base.html.twig' %}
{% block body -%}
<h1>BlopEntity2 edit</h1>
{{ form(edit_form) }}
<ul class="record_actions">
<li>
<a href="{{ path('blopentity2') }}">
Back to the list
</a>
</li>
<li>{{ form(delete_form) }}</li>
</ul>
{% endblock %}

View File

@ -0,0 +1,41 @@
{% extends '::base.html.twig' %}
{% block body -%}
<h1>BlopEntity2 list</h1>
<table class="records_list">
<thead>
<tr>
<th>Id</th>
<th>CustomfieldData</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for entity in entities %}
<tr>
<td><a href="{{ path('blopentity2_show', { 'id': entity.id }) }}">{{ entity.id }}</a></td>
<td>{{ entity.CustomfieldData }}</td>
<td>
<ul>
<li>
<a href="{{ path('blopentity2_show', { 'id': entity.id }) }}">show</a>
</li>
<li>
<a href="{{ path('blopentity2_edit', { 'id': entity.id }) }}">edit</a>
</li>
</ul>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<ul>
<li>
<a href="{{ path('blopentity2_new') }}">
Create a new entry
</a>
</li>
</ul>
{% endblock %}

View File

@ -0,0 +1,15 @@
{% extends '::base.html.twig' %}
{% block body -%}
<h1>BlopEntity2 creation</h1>
{{ form(form) }}
<ul class="record_actions">
<li>
<a href="{{ path('blopentity2') }}">
Back to the list
</a>
</li>
</ul>
{% endblock %}

View File

@ -0,0 +1,32 @@
{% extends '::base.html.twig' %}
{% block body -%}
<h1>BlopEntity2</h1>
<table class="record_properties">
<tbody>
<tr>
<th>Id</th>
<td>{{ entity.id }}</td>
</tr>
<tr>
<th>CustomfieldData</th>
<td>{{ entity.customFieldData }}</td>
</tr>
</tbody>
</table>
<ul class="record_actions">
<li>
<a href="{{ path('blopentity2') }}">
Back to the list
</a>
</li>
<li>
<a href="{{ path('blopentity2_edit', { 'id': entity.id }) }}">
Edit
</a>
</li>
<li>{{ form(delete_form) }}</li>
</ul>
{% endblock %}

View File

@ -0,0 +1,55 @@
<?php
namespace CL\CustomFieldsBundle\Tests\Controller;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class BlopEntity2ControllerTest extends WebTestCase
{
/*
public function testCompleteScenario()
{
// Create a new client to browse the application
$client = static::createClient();
// Create a new entry in the database
$crawler = $client->request('GET', '/blopentity2/');
$this->assertEquals(200, $client->getResponse()->getStatusCode(), "Unexpected HTTP status code for GET /blopentity2/");
$crawler = $client->click($crawler->selectLink('Create a new entry')->link());
// Fill in the form and submit it
$form = $crawler->selectButton('Create')->form(array(
'cl_customfieldsbundle_blopentity2[field_name]' => 'Test',
// ... other fields to fill
));
$client->submit($form);
$crawler = $client->followRedirect();
// Check data in the show view
$this->assertGreaterThan(0, $crawler->filter('td:contains("Test")')->count(), 'Missing element td:contains("Test")');
// Edit the entity
$crawler = $client->click($crawler->selectLink('Edit')->link());
$form = $crawler->selectButton('Update')->form(array(
'cl_customfieldsbundle_blopentity2[field_name]' => 'Foo',
// ... other fields to fill
));
$client->submit($form);
$crawler = $client->followRedirect();
// Check the element contains an attribute with value equals "Foo"
$this->assertGreaterThan(0, $crawler->filter('[value="Foo"]')->count(), 'Missing element [value="Foo"]');
// Delete the entity
$client->submit($crawler->selectButton('Delete')->form());
$crawler = $client->followRedirect();
// Check the entity has been delete on the list
$this->assertNotRegExp('/Foo/', $client->getResponse()->getContent());
}
*/
}