Not exprexted behaviour on symfony datatransformer - symfony

I created a datatransformer to store dates on unixtime on the database but show it as datetime on the form
this is the transformer
class IntegerToTimestampTransformer implements DataTransformerInterface
{
public function transform($timestamp)
{
/**
* This if sentenceis because when eidt $timestamp is a timestamp(unix)
* but when create is a DateTime ¿¿???
*/
if($timestamp instanceof \DateTime){
return $timestamp;
}
return (new \DateTime())->setTimestamp($timestamp);
}
public function reverseTransform($datetime)
{
if ($datetime === null) {
return $datetime;
}
return $datetime->getTimestamp();
}
}
this is the entity
/**
* Popup
*
* #ORM\Table(name="popup")
* #ORM\Entity(repositoryClass="AppBundle\Repository\PopUpRepository")
*/
class Popup
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #Gedmo\Translatable()
* #ORM\Column(name="title", type="string", length=255)
*/
private $title;
/**
* #var string
*
* #Gedmo\Translatable()
* #ORM\Column(name="description", type="text")
*/
private $description;
/**
* #var int
*
* #ORM\Column(name="activation_date", type="integer", nullable=true)
*/
private $activationDate;
/**
* #var int
*
* #ORM\Column(name="deactivation_date", type="integer", nullable=true)
*/
private $deactivationDate;
/**
* #var boolean
*
* #ORM\Column(name="active", type="boolean")
*/
private $active;
/**
* #var Collection
*
* #ORM\ManyToMany(targetEntity="AppBundle\Entity\Role")
* #ORM\JoinTable(name="popup_role", joinColumns={#ORM\JoinColumn(name="popup_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="role_id", referencedColumnName="id")})
*/
private $roles;
public function __construct()
{
$this->roles = new ArrayCollection();
}
/**
* #return int
*/
public function getId(): int
{
return $this->id;
}
/**
* #param int $id
*/
public function setId(int $id): void
{
$this->id = $id;
}
/**
* #return string
*/
public function getTitle():? string
{
return $this->title;
}
/**
* #param string $title
*/
public function setTitle(string $title): void
{
$this->title = $title;
}
/**
* #return string
*/
public function getDescription(): ?string
{
return $this->description;
}
/**
* #param string $description
*/
public function setDescription(string $description): void
{
$this->description = $description;
}
/**
* #return int
*/
public function getActivationDate(): ?int
{
return $this->activationDate;
}
/**
* #param int $activationDate
*/
public function setActivationDate(int $activationDate): void
{
$this->activationDate = $activationDate;
}
/**
* #return int
*/
public function getDeactivationDate(): ?int
{
return $this->deactivationDate;
}
/**
* #param int $deactivationDate
*/
public function setDeactivationDate(int $deactivationDate): void
{
$this->deactivationDate = $deactivationDate;
}
/**
* #return bool
*/
public function isActive(): ?bool
{
return $this->active;
}
/**
* #param bool $active
*/
public function setActive(bool $active): void
{
$this->active = $active;
}
/**
* Add role
*
* #param Role $role
*
* #return Role
*/
public function addRole(Role $role)
{
$this->roles[] = $role;
return $this;
}
/**
* Remove role
*
* #param Role $role
*/
public function removeRole(Role $role)
{
$this->roles->removeElement($role);
}
/**
* Get role
*
* #return Collection
*/
public function getRoles()
{
return $this->roles;
}
}
and the formtype
class PopupType extends AbstractType
{
private $tranformer;
public function __construct(IntegerToTimestampTransformer $tranformer){
$this->tranformer = $tranformer;
}
/**
* {#inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$date_array = [
'label_attr' => [
'class' => 'font-weight-bold'
],
'required' => false
];
if(!$options['edit']){
$date_array['data'] = new \DateTime();
}
$builder
->add('title', TextType::class, [
'label_attr' => [
'class' => 'font-weight-bold'
],
])
->add('description', TextareaType::class, [
'label_attr' => [
'class' => 'font-weight-bold'
],
'required' => false
])
->add('activation_date', DateTimeType::class, $date_array)
->add('deactivation_date', DateTimeType::class,$date_array)
->add('active', CheckboxType::class, [
'label_attr' => [
'class' => 'font-weight-bold'
],
'required' => false
])
->add('roles', EntityType::class, [
'class' => Role::class,
'expanded' => true,
'multiple' => true,
'required' => true,
'label_attr' => [
'class' => 'font-weight-bold'
],
])
;
$builder->get('activation_date')->addModelTransformer($this->tranformer);
$builder->get('deactivation_date')->addModelTransformer($this->tranformer);
}
/**
* {#inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => Popup::class,
'edit' => false
));
}
/**
* {#inheritdoc}
*/
public function getBlockPrefix()
{
return 'appbundle_popup';
}
}
I debugged and I checked that in the transform function when I try to create on the crud the parameter passed to transform is a Datetime the there is no need to transformate the data but when I try to edit the parameter passed to transform is a unixtime integer the the transformation is needed, I don't understant that behaviour.

Related

Symfony 4 - Can't create Entity

I'm using Sonata Admin for the first time, I followed doc online and my admin works well, except I have an error when I try to create elements via my admin:
Failed to create object: App\Entity\HomeBlockElement
I have my HomeBlockElement
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity(repositoryClass="App\Repository\HomeBlockElementRepository")
* #ORM\Table(name="home_block_element")
*/
class HomeBlockElement
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(name="home_element_id",type="integer")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="home_element_title", type="string", length=255)
*/
protected $title;
/**
* #var string
*
* #ORM\Column(name="home_element_text_link", type="string", length=255)
*/
protected $textLink;
/**
* #var string
*
* #ORM\Column(name="home_element_shopping_link", type="string", length=255)
*/
protected $shoppingLink;
/**
* #var string
*
* #ORM\Column(name="home_element_marketing_etiquette", type="string", length=255)
*/
protected $marketingEtiquette;
/**
* #var string
*
* #ORM\Column(name="home_element_media", type="text")
*/
protected $media;
/**
* #var bool
*
* #ORM\Column(name="home_element_published", type="boolean")
*/
protected $published = false;
public function getId(): ?int
{
return $this->id;
}
/**
* #return string
*/
public function getTitle(): ?string
{
return $this->title;
}
/**
* #param string $title
* #return HomeBlockElement
*/
public function setTitle(?string $title): HomeBlockElement
{
$this->title = $title;
return $this;
}
/**
* #return string
*/
public function getTextLink(): ?string
{
return $this->textLink;
}
/**
* #param string $textLink
* #return HomeBlockElement
*/
public function setTextLink(?string $textLink): HomeBlockElement
{
$this->textLink = $textLink;
return $this;
}
/**
* #return string
*/
public function getShoppingLink(): ?string
{
return $this->shoppingLink;
}
/**
* #param string $shoppingLink
* #return HomeBlockElement
*/
public function setShoppingLink(?string $shoppingLink): HomeBlockElement
{
$this->shoppingLink = $shoppingLink;
return $this;
}
/**
* #return string
*/
public function getMarketingEtiquette(): ?string
{
return $this->marketingEtiquette;
}
/**
* #param string $categoryLink
* #return HomeBlockElement
*/
public function setMarketingEtiquette(?string $marketingEtiquette): HomeBlockElement
{
$this->marketingEtiquette = $marketingEtiquette;
return $this;
}
/**
* #return bool
*/
public function isPublished(): bool
{
return $this->published;
}
/**
* #param bool $published
* #return Page
*/
public function setPublished(bool $published): HomeBlockElement
{
$this->published = $published;
return $this;
}
}
And my HomeBlockElementAdmin:
<?php
namespace App\Admin;
use App\Entity\Page;
use FOS\CKEditorBundle\Form\Type\CKEditorType;
use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Route\RouteCollection;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
final class HomeBlockElementAdmin extends AbstractAdmin
{
protected $datagridValues = array(
'_sort_order' => 'ASC',
'_sort_by' => 'title',
);
/**
* #param $object
* #return string|null
*/
public function toString($object): ?string
{
return $object instanceof Page && $object->getTitle()
? $object->getTitle()
: 'Nouveau bloc élément';
}
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->with('Contenu')
->add('published', CheckboxType::class, ['required' => false, 'label' => 'Publier'])
->add('title', TextType::class, ['required' => true, 'label' => 'Titre'])
->add('marketingEtiquette', TextType::class, ['required' => false, 'label' => 'Etiquette Marketing'])
->add('textLink', TextType::class, ['required' => true, 'label' => 'Texte'])
->add('shoppinglink', TextType::class, ['required' => true, 'label' => 'Lien'])
->end();
}
protected function configureListFields(ListMapper $listMapper)
{
unset($this->listModes['mosaic']);
$listMapper
->addIdentifier('title')
->addIdentifier('marketingEtiquette')
->addIdentifier('textLink')
->addIdentifier('shoppinglink')
->addIdentifier('published')
;
}
protected function configureDatagridFilters(DatagridMapper $datagridMapper)
{
$datagridMapper
->add('title')
->add('marketingEtiquette')
->add('textLink')
->add('shoppinglink')
->add('published');
}
/**
* #param RouteCollection $collection
*/
protected function configureRoutes(RouteCollection $collection)
{
$collection
->remove('delete')
//->remove('create')
->add('move', $this->getRouterIdParameter() . '/move/{position}');
}
}
I then defined this in my services.yaml
admin.element:
class: App\Admin\HomeBlockElementAdmin
arguments: [~, App\Entity\HomeBlockElement, ~]
tags:
- { name: sonata.admin, manager_type: orm, label: 'Element blocs', group: 'app.admin.group.home' }
I've updated the data base with php bin/console doctrine:schema:update to make it match with my code and everything worked fine.From what I saw on the Internet, the error is related to SQL but
I can't see where the error comes from.
In the breadrcumb from the error I can see:
PDOException > PDOException > NotNullConstraintViolationException > ModelManagerException
So the error is because something is null when it shouldn't? But the only thing that is required is the id, and it should be generated automatically... I don't know what to do

Using BeelabTagBundle library on symfony

I am trying to use BeelabTagBundle library to implements tags on my website. But I am in a lack of information to do so. Here is where I am at now:
Installed via composer
Created an entity that implements "TaggableInterface" with some personals fields, and the requested ones in the documentation.
/**
* Constructor
*/
public function __construct()
{
$this->keywords = new ArrayCollection();
}
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id = null;
/**
* #ORM\Column(type="string", length=255)
*/
private $type;
/**
* #ORM\Column(type="string", length=255)
*/
private $fileName;
/**
* #ORM\Column(type="boolean")
*/
private $active;
/**
* #var ArrayCollection
*
* #ORM\ManyToMany(targetEntity="Tag")
*/
private $keywords;
private $tagsText;
/**
* #ORM\Column(type="datetime", nullable=true)
*/
private $updated;
/**
* {#inheritdoc}
*/
public function addTag(TagInterface $tag)
{
$this->keywords[] = $tag;
}
/**
* {#inheritdoc}
*/
public function removeTag(TagInterface $tag)
{
$this->keywords->removeElement($tag);
}
/**
* {#inheritdoc}
*/
public function hasTag(TagInterface $tag)
{
return $this->keywords->contains($tag);
}
/**
* {#inheritdoc}
*/
public function getTags()
{
return $this->keywords;
}
/**
* {#inheritdoc}
*/
public function getTagNames(): array
{
return empty($this->tagsText) ? [] : array_map('trim', explode(',', $this->tagsText));
}
/**
* #param string
*/
public function setTagsText($tagsText)
{
$this->tagsText = $tagsText;
$this->updated = new \DateTime();
}
/**
* #return string
*/
public function getTagsText()
{
$this->tagsText = implode(', ', $this->keywords->toArray());
return $this->tagsText;
}
Have my route to get the json of my tags (working when calling it but empty)
/**
* #Route("/miseenpage/keywords.json", name="keywords", defaults={"_format": "json"})
*/
public function tagsAction() {
$tags = $this->getDoctrine()->getRepository(Tag::class)->findBy([], ['name' => 'ASC']);
return $this->render('miseenpage/keywords.html.twig', ['tags' => $tags]);
}
I also followed the Javascript enhancement, So I now have created a "TagsTextType"
class TagsTextType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('tagsText', TextType::class, ['required' => false, 'label' => 'Tags'])
;
}
/**
* #var RouterInterface $route
*/
private $router;
/**
* #param RouterInterface $router
*/
public function __construct(RouterInterface $router)
{
$this->router = $router;
}
/**
* {#inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'required' => false,
'label' => 'Tags',
'attr' => [
'placeholder' => 'separate tags with comma',
'data-ajax' => $this->router->generate('keywords'),
],
]);
}
/**
* {#inheritdoc}
*/
public function getParent()
{
return TextType::class;
}
}
How can I show my tag field now (alongside with all my other data from my entity) ? This is not detailed in the documentation. Thanks

Adding datatables to symfony 3 - data not showing

I tried installing datatables to my Symfony 3 project. I'm new to this and not sure where I went wrong but the data from my MySQL database are not showing.
I have {{ datatable_render(datatable) }} on my index page but all it shows in a button to add another entry.
This is my controller
namespace AppBundle\Controller;
use AppBundle\Entity\Shrubs;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;use Symfony\Component\HttpFoundation\Request;
/**
* Shrub controller.
*
* #Route("shrubs")
*/
class ShrubsController extends Controller
{
/**
* Lists all shrub entities.
*
* #Route("/", name="shrubs_index")
* #Method("GET")
*/
public function indexAction()
{
$datatable = $this->get('app.datatable.shrubs');
$datatable->buildDatatable();
// $em = $this->getDoctrine()->getManager();
// $datatable = $em->getRepository('AppBundle:Shrubs')->findAll();
return $this->render('shrubs/index.html.twig', array(
'datatable' => $datatable,
// 'shrubs' => $shrubs,
));
}
/**
* #Route("/results", name="shrubs_results")
*/
public function indexResultsAction()
{
$datatable = $this->get('app.datatable.shrubs');
$datatable->buildDatatable();
$query = $this->get('shrubs_datatable')->getQueryFrom($datatable);
return $query->getResponse();
}
ShrubDatatable
<?php
namespace AppBundle\Datatables;
use Sg\DatatablesBundle\Datatable\View\AbstractDatatableView;
use Sg\DatatablesBundle\Datatable\View\Style;
/**
* Class ShrubsDatatable
*
* #package AppBundle\Datatables
*/
class ShrubsDatatable extends AbstractDatatableView
{
/**
* {#inheritdoc}
*/
public function buildDatatable(array $options = array())
{
$this->topActions->set(array(
'start_html' => '<div class="row"><div class="col-sm-3">',
'end_html' => '<hr></div></div>',
'actions' => array(
array(
'route' => $this->router->generate('shrubs_new'),
'label' => $this->translator->trans('datatables.actions.new'),
'icon' => 'glyphicon glyphicon-plus',
'attributes' => array(
'rel' => 'tooltip',
'title' => $this->translator->trans('datatables.actions.new'),
'class' => 'btn btn-primary',
'role' => 'button'
),
)
)
));
$this->features->set(array(
'auto_width' => true,
'defer_render' => false,
'info' => true,
'jquery_ui' => false,
'length_change' => true,
'ordering' => true,
'paging' => true,
'processing' => true,
'scroll_x' => false,
'scroll_y' => '',
'searching' => true,
'state_save' => false,
'delay' => 0,
'extensions' => array(),
'highlight' => false,
'highlight_color' => 'red'
));
$this->ajax->set(array(
'url' => $this->router->generate('shrubs_index'),
'type' => 'GET',
'pipeline' => 0
));
$this->options->set(array(
'display_start' => 0,
'defer_loading' => -1,
'dom' => 'lfrtip',
'length_menu' => array(10, 25, 50, 100),
'order_classes' => true,
'order' => array(array(0, 'asc')),
'order_multi' => true,
'page_length' => 10,
'paging_type' => Style::FULL_NUMBERS_PAGINATION,
'renderer' => '',
'scroll_collapse' => false,
'search_delay' => 0,
'state_duration' => 7200,
'stripe_classes' => array(),
'class' => Style::BOOTSTRAP_3_STYLE,
'individual_filtering' => false,
'individual_filtering_position' => 'head',
'use_integration_options' => true,
'force_dom' => false,
'row_id' => 'id'
));
$this->columnBuilder
->add('botanicalname', 'column', array(
'title' => 'Botanicalname',
))
->add('commonname', 'column', array(
'title' => 'Commonname',
))
->add('borderlinehardy', 'column', array(
'title' => 'Borderlinehardy',
))
->add('phpreference', 'column', array(
'title' => 'Phpreference',
))
->add('wetsoil', 'column', array(
'title' => 'Wetsoil',
))
->add('moistsoil', 'column', array(
'title' => 'Moistsoil',
))
->add('peatysoil', 'column', array(
'title' => 'Peatysoil',
))
->add('welldrainedsoil', 'column', array(
'title' => 'Welldrainedsoil',
))
->add('drought', 'column', array(
'title' => 'Drought',
))
->add('claysoil', 'column', array(
'title' => 'Claysoil',
))
->add('sandysoil', 'column', array(
'title' => 'Sandysoil',
))
->add('loamsoil', 'column', array(
'title' => 'Loamsoil',
))
->add('infertilesoil', 'column', array(
'title' => 'Infertilesoil',
))
->add('richsoil', 'column', array(
'title' => 'Richsoil',
))
->add('compactedsoil', 'column', array(
'title' => 'Compactedsoil',
))
->add('cityconditions', 'column', array(
'title' => 'Cityconditions',
))
->add('pollution', 'column', array(
'title' => 'Pollution',
))
->add('salt', 'column', array(
'title' => 'Salt',
))
->add('windy', 'column', array(
'title' => 'Windy',
))
->add('shade', 'column', array(
'title' => 'Shade',
))
->add('partshade', 'column', array(
'title' => 'Partshade',
))
->add('fullsun', 'column', array(
'title' => 'Fullsun',
))
->add('pestproblem', 'column', array(
'title' => 'Pestproblem',
))
->add('id', 'column', array(
'title' => 'Id',
))
->add(null, 'action', array(
'title' => $this->translator->trans('datatables.actions.title'),
'actions' => array(
array(
'route' => 'shrubs_show',
'route_parameters' => array(
'id' => 'id'
),
'label' => $this->translator->trans('datatables.actions.show'),
'icon' => 'glyphicon glyphicon-eye-open',
'attributes' => array(
'rel' => 'tooltip',
'title' => $this->translator->trans('datatables.actions.show'),
'class' => 'btn btn-primary btn-xs',
'role' => 'button'
),
),
array(
'route' => 'shrubs_edit',
'route_parameters' => array(
'id' => 'id'
),
'label' => $this->translator->trans('datatables.actions.edit'),
'icon' => 'glyphicon glyphicon-edit',
'attributes' => array(
'rel' => 'tooltip',
'title' => $this->translator->trans('datatables.actions.edit'),
'class' => 'btn btn-primary btn-xs',
'role' => 'button'
),
)
)
))
;
}
/**
* {#inheritdoc}
*/
public function getEntity()
{
return 'AppBundle\Entity\Shrubs';
}
/**
* {#inheritdoc}
*/
public function getName()
{
return 'shrubs_datatable';
}
}
Entity\Shrubs
<?php
namespace AppBundle\Entity;
/**
* Shrubs
*/
class Shrubs
{
/**
* #var string
*/
private $botanicalname;
/**
* #var string
*/
private $commonname;
/**
* #var string
*/
private $borderlinehardy;
/**
* #var string
*/
private $phpreference;
/**
* #var string
*/
private $wetsoil;
/**
* #var string
*/
private $moistsoil;
/**
* #var string
*/
private $peatysoil;
/**
* #var string
*/
private $welldrainedsoil;
/**
* #var string
*/
private $drought;
/**
* #var string
*/
private $claysoil;
/**
* #var string
*/
private $sandysoil;
/**
* #var string
*/
private $loamsoil;
/**
* #var string
*/
private $infertilesoil;
/**
* #var string
*/
private $richsoil;
/**
* #var string
*/
private $compactedsoil;
/**
* #var string
*/
private $cityconditions;
/**
* #var string
*/
private $pollution;
/**
* #var string
*/
private $salt;
/**
* #var string
*/
private $windy;
/**
* #var string
*/
private $shade;
/**
* #var string
*/
private $partshade;
/**
* #var string
*/
private $fullsun;
/**
* #var string
*/
private $pestproblem;
/**
* #var integer
*/
private $id;
/**
* Set botanicalname
*
* #param string $botanicalname
*
* #return Shrubs
*/
public function setBotanicalname($botanicalname)
{
$this->botanicalname = $botanicalname;
return $this;
}
/**
* Get botanicalname
*
* #return string
*/
public function getBotanicalname()
{
return $this->botanicalname;
}
/**
* Set commonname
*
* #param string $commonname
*
* #return Shrubs
*/
public function setCommonname($commonname)
{
$this->commonname = $commonname;
return $this;
}
/**
* Get commonname
*
* #return string
*/
public function getCommonname()
{
return $this->commonname;
}
/**
* Set borderlinehardy
*
* #param string $borderlinehardy
*
* #return Shrubs
*/
public function setBorderlinehardy($borderlinehardy)
{
$this->borderlinehardy = $borderlinehardy;
return $this;
}
/**
* Get borderlinehardy
*
* #return string
*/
public function getBorderlinehardy()
{
return $this->borderlinehardy;
}
/**
* Set phpreference
*
* #param string $phpreference
*
* #return Shrubs
*/
public function setPhpreference($phpreference)
{
$this->phpreference = $phpreference;
return $this;
}
/**
* Get phpreference
*
* #return string
*/
public function getPhpreference()
{
return $this->phpreference;
}
/**
* Set wetsoil
*
* #param string $wetsoil
*
* #return Shrubs
*/
public function setWetsoil($wetsoil)
{
$this->wetsoil = $wetsoil;
return $this;
}
/**
* Get wetsoil
*
* #return string
*/
public function getWetsoil()
{
return $this->wetsoil;
}
/**
* Set moistsoil
*
* #param string $moistsoil
*
* #return Shrubs
*/
public function setMoistsoil($moistsoil)
{
$this->moistsoil = $moistsoil;
return $this;
}
/**
* Get moistsoil
*
* #return string
*/
public function getMoistsoil()
{
return $this->moistsoil;
}
/**
* Set peatysoil
*
* #param string $peatysoil
*
* #return Shrubs
*/
public function setPeatysoil($peatysoil)
{
$this->peatysoil = $peatysoil;
return $this;
}
/**
* Get peatysoil
*
* #return string
*/
public function getPeatysoil()
{
return $this->peatysoil;
}
/**
* Set welldrainedsoil
*
* #param string $welldrainedsoil
*
* #return Shrubs
*/
public function setWelldrainedsoil($welldrainedsoil)
{
$this->welldrainedsoil = $welldrainedsoil;
return $this;
}
/**
* Get welldrainedsoil
*
* #return string
*/
public function getWelldrainedsoil()
{
return $this->welldrainedsoil;
}
/**
* Set drought
*
* #param string $drought
*
* #return Shrubs
*/
public function setDrought($drought)
{
$this->drought = $drought;
return $this;
}
/**
* Get drought
*
* #return string
*/
public function getDrought()
{
return $this->drought;
}
/**
* Set claysoil
*
* #param string $claysoil
*
* #return Shrubs
*/
public function setClaysoil($claysoil)
{
$this->claysoil = $claysoil;
return $this;
}
/**
* Get claysoil
*
* #return string
*/
public function getClaysoil()
{
return $this->claysoil;
}
/**
* Set sandysoil
*
* #param string $sandysoil
*
* #return Shrubs
*/
public function setSandysoil($sandysoil)
{
$this->sandysoil = $sandysoil;
return $this;
}
/**
* Get sandysoil
*
* #return string
*/
public function getSandysoil()
{
return $this->sandysoil;
}
/**
* Set loamsoil
*
* #param string $loamsoil
*
* #return Shrubs
*/
public function setLoamsoil($loamsoil)
{
$this->loamsoil = $loamsoil;
return $this;
}
/**
* Get loamsoil
*
* #return string
*/
public function getLoamsoil()
{
return $this->loamsoil;
}
/**
* Set infertilesoil
*
* #param string $infertilesoil
*
* #return Shrubs
*/
public function setInfertilesoil($infertilesoil)
{
$this->infertilesoil = $infertilesoil;
return $this;
}
/**
* Get infertilesoil
*
* #return string
*/
public function getInfertilesoil()
{
return $this->infertilesoil;
}
/**
* Set richsoil
*
* #param string $richsoil
*
* #return Shrubs
*/
public function setRichsoil($richsoil)
{
$this->richsoil = $richsoil;
return $this;
}
/**
* Get richsoil
*
* #return string
*/
public function getRichsoil()
{
return $this->richsoil;
}
/**
* Set compactedsoil
*
* #param string $compactedsoil
*
* #return Shrubs
*/
public function setCompactedsoil($compactedsoil)
{
$this->compactedsoil = $compactedsoil;
return $this;
}
/**
* Get compactedsoil
*
* #return string
*/
public function getCompactedsoil()
{
return $this->compactedsoil;
}
/**
* Set cityconditions
*
* #param string $cityconditions
*
* #return Shrubs
*/
public function setCityconditions($cityconditions)
{
$this->cityconditions = $cityconditions;
return $this;
}
/**
* Get cityconditions
*
* #return string
*/
public function getCityconditions()
{
return $this->cityconditions;
}
/**
* Set pollution
*
* #param string $pollution
*
* #return Shrubs
*/
public function setPollution($pollution)
{
$this->pollution = $pollution;
return $this;
}
/**
* Get pollution
*
* #return string
*/
public function getPollution()
{
return $this->pollution;
}
/**
* Set salt
*
* #param string $salt
*
* #return Shrubs
*/
public function setSalt($salt)
{
$this->salt = $salt;
return $this;
}
/**
* Get salt
*
* #return string
*/
public function getSalt()
{
return $this->salt;
}
/**
* Set windy
*
* #param string $windy
*
* #return Shrubs
*/
public function setWindy($windy)
{
$this->windy = $windy;
return $this;
}
/**
* Get windy
*
* #return string
*/
public function getWindy()
{
return $this->windy;
}
/**
* Set shade
*
* #param string $shade
*
* #return Shrubs
*/
public function setShade($shade)
{
$this->shade = $shade;
return $this;
}
/**
* Get shade
*
* #return string
*/
public function getShade()
{
return $this->shade;
}
/**
* Set partshade
*
* #param string $partshade
*
* #return Shrubs
*/
public function setPartshade($partshade)
{
$this->partshade = $partshade;
return $this;
}
/**
* Get partshade
*
* #return string
*/
public function getPartshade()
{
return $this->partshade;
}
/**
* Set fullsun
*
* #param string $fullsun
*
* #return Shrubs
*/
public function setFullsun($fullsun)
{
$this->fullsun = $fullsun;
return $this;
}
/**
* Get fullsun
*
* #return string
*/
public function getFullsun()
{
return $this->fullsun;
}
/**
* Set pestproblem
*
* #param string $pestproblem
*
* #return Shrubs
*/
public function setPestproblem($pestproblem)
{
$this->pestproblem = $pestproblem;
return $this;
}
/**
* Get pestproblem
*
* #return string
*/
public function getPestproblem()
{
return $this->pestproblem;
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
}
I went through a tutorial and auto generated the datatables so I'm not sure what other info is needed. Please let me know and I'll add it.

Collection form return array instead object in relation OneToMany

I have a problem, I have two entitys, Contenu(One) and Article(Many), I have make my relation, who it bidirectionnal.
I use FormType imbricate and when I submit my form, I have an array for my entity Article instead an object, and I can't persist with an array.
If you have any solution, thanks
Entity Contenu
<?php
/**
* Contenu
*
* #ORM\Table(name="ge_contenu")
* #ORM\Entity(repositoryClass="GE\MainBundle\Repository\ContenuRepository")
*/
class Contenu
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="entete", type="text")
*/
private $entete;
/**
* #var string
*
* #ORM\Column(name="texte", type="text")
*/
private $texte;
/**
* #var string
*
* #ORM\Column(name="conclusion", type="text")
*/
private $conclusion;
/**
* #ORM\OneToMany(targetEntity="AdminBundle\Entity\Article", mappedBy="contenu")
*/
private $articles;
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set texte
*
* #param string $texte
*
* #return Contenu
*/
public function setTexte($texte)
{
$this->texte = $texte;
return $this;
}
/**
* Get texte
*
* #return string
*/
public function getTexte()
{
return $this->texte;
}
/**
* Set entete
*
* #param string $entete
*
* #return Contenu
*/
public function setEntete($entete)
{
$this->entete = $entete;
return $this;
}
/**
* Get entete
*
* #return string
*/
public function getEntete()
{
return $this->entete;
}
/**
* Set conclusion
*
* #param string $conclusion
*
* #return Contenu
*/
public function setConclusion($conclusion)
{
$this->conclusion = $conclusion;
return $this;
}
/**
* Get conclusion
*
* #return string
*/
public function getConclusion()
{
return $this->conclusion;
}
/**
* Constructor
*/
public function __construct()
{
$this->articles = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Add article
*
* #param \AdminBundle\Entity\Article $article
*
* #return Contenu
*/
public function addArticle(\AdminBundle\Entity\Article $article)
{
$this->articles[] = $article;
$article->setContenu($this);
return $this;
}
/**
* Remove article
*
* #param \AdminBundle\Entity\Article $article
*/
public function removeArticle(\AdminBundle\Entity\Article $article)
{
$this->articles->removeElement($article);
}
/**
* Get articles
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getArticles()
{
return $this->articles;
}
}
Entity Article
<?php
/**
* Article
*
* #ORM\Table(name="ge_article")
* #ORM\Entity(repositoryClass="GE\MainBundle\Repository\ArticleRepository")
*/
class Article
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="titre", type="string", length=150)
*/
private $titre;
/**
* #var string
*
* #ORM\Column(name="texte", type="text")
*/
private $texte;
/**
* #var Article $article
*
* #ORM\ManyToOne(targetEntity="AdminBundle\Entity\Contenu", inversedBy="articles")
* #ORM\JoinColumn(nullable=false)
*/
public $contenu;
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set titre
*
* #param string $titre
*
* #return Article
*/
public function setTitre($titre)
{
$this->titre = $titre;
return $this;
}
/**
* Get titre
*
* #return string
*/
public function getTitre()
{
return $this->titre;
}
/**
* Set texte
*
* #param string $texte
*
* #return Article
*/
public function setTexte($texte)
{
$this->texte = $texte;
return $this;
}
/**
* Get texte
*
* #return string
*/
public function getTexte()
{
return $this->texte;
}
/**
* Set contenu
*
* #param \AdminBundle\Entity\Contenu $contenu
*
* #return Article
*/
public function setContenu(\AdminBundle\Entity\Contenu $contenu)
{
$this->contenu = $contenu;
return $this;
}
/**
* Get contenu
*
* #return \AdminBundle\Entity\Contenu
*/
public function getContenu()
{
return $this->contenu;
}
}
My controller
public function contenuAction($id = null, Request $request)
{
$em = $this
->getDoctrine()
->getManager()
;
$pages_contenu = $em->getRepository('AdminBundle:Page')->findBy(
array("contenu" => true),
array("nom" => "asc"),
null,
null
);
$vars = array(
"modif" => null,
"modif" => null,
"pages_contenu" => $pages_contenu
);
if (isset($id))
{
$contenu = $em->getRepository('AdminBundle:Contenu')->findOneById($id);
if ($contenu == null)
{
$contenu = new Contenu();
$vars["modif"] = $contenu;
}
else
{
$vars["modif"] = $contenu;
}
}
else
{
$contenu = new Contenu();
}
$form = $this->get('form.factory')->create(ContenuType::class, $contenu);
if ($request->isMethod('POST') && $form->handleRequest($request)->isValid())
{
$em->persist($contenu);
$em->flush();
$request->getSession()->getFlashBag()->set('valid', 'Contenu bien enregistré.');
return $this->redirectToRoute('admin_contenu');
}
$vars['form'] = $form->createView();
return $this->render('AdminBundle:Admin:contenu.html.twig', $vars);
}
Contenu Type
class ContenuType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('entete', TextareaType::class)
->add('texte', TextareaType::class)
->add('articles', CollectionType::class, array(
'entry_type' => ArticleType::class,
'allow_add' => true,
'allow_delete' => true
))
->add('conclusion', TextareaType::class)
->add('submit', SubmitType::class, array('label' => 'Enregistrer'))
;
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AdminBundle\Entity\Contenu'
));
}
public function getName()
{
return 'adminbundle_contenu';
}
}
Article Type
class ArticleType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('titre', TextType::class)
->add('texte', TextareaType::class)
;
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AdminBundle\Entity\Article'
));
}
public function getName()
{
return 'adminbundle_article';
}
}
You have to add the following method to your ArticleType class:
public function configureOptions(OptionsResolver $resolver) {
$resolver->setDefaults(array(
'data_class' => 'AdminBundle\Entity\ArticleType'
));
}

Symfony2 try to insert ManyToMany relation before insert one part of both sides

I have this Entities:
<?php
namespace ProductBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use ProductBundle\DBAL\Types\StatusType;
use ProductBundle\DBAL\Types\FieldType;
use Fresh\Bundle\DoctrineEnumBundle\Validator\Constraints as DoctrineAssert;
/**
* #ORM\Entity
* #ORM\Table(name="product_detail")
*/
class ProductDetail {
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\ManyToOne(targetEntity="ProductDetail")
* #ORM\JoinColumn(name="parent", referencedColumnName="id")
*/
protected $parent;
/**
* #ORM\Column(type="string", length=255)
*/
protected $description;
/**
* #ORM\Column(type="string", length=255)
*/
protected $label;
/**
* #var string $field_type
* #DoctrineAssert\Enum(entity="ProductBundle\DBAL\Types\FieldType")
* #ORM\Column(name="field_type", type="FieldType", nullable=false)
*/
protected $field_type;
/**
* #ORM\Column(name="values_text", type="string")
*/
protected $values_text;
/**
* #ORM\Column(type="string", length=255)
*/
protected $measure_unit;
/**
* #var string $status
* #DoctrineAssert\Enum(entity="ProductBundle\DBAL\Types\StatusType")
* #ORM\Column(name="status", type="StatusType", nullable=false)
*/
protected $status;
/**
* #Gedmo\Timestampable(on="create")
* #ORM\Column(name="created", type="datetime")
*/
protected $created;
/**
* #Gedmo\Timestampable(on="update")
* #ORM\Column(name="modified", type="datetime")
*/
protected $modified;
/**
* #ORM\ManyToMany(targetEntity="CategoryBundle\Entity\Category", inversedBy="pd_detail")
* #ORM\JoinTable(name="product_detail_has_category",
* joinColumns={#ORM\JoinColumn(name="category", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="detail", referencedColumnName="id")}
* )
*/
protected $category;
/**
* #ORM\ManyToMany(targetEntity="ProductBundle\Entity\DetailGroup", inversedBy="productDetail")
* #ORM\JoinTable(name="detail_group_has_product_detail",
* joinColumns={#ORM\JoinColumn(name="group", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="detail", referencedColumnName="id")}
* )
*/
protected $detail_group;
public function __construct() {
$this->detail_group = new \Doctrine\Common\Collections\ArrayCollection();
$this->category = new \Doctrine\Common\Collections\ArrayCollection();
}
public function getId() {
return $this->id;
}
public function setParent(ProductDetail $parent = null) {
$this->parent = $parent;
}
public function getParent() {
return $this->parent;
}
public function setDescription($description) {
$this->description = $description;
}
public function getDescription() {
return $this->description;
}
public function setLabel($label) {
$this->label = $label;
}
public function getLabel() {
return $this->label;
}
public function setFieldType($field_type) {
$this->field_type = $field_type;
}
public function getFieldType() {
return $this->field_type;
}
public function setValuesText($values_text) {
$this->values_text = $values_text;
}
public function getValuesText() {
return $this->values_text;
}
public function setMeasureUnit($measure_unit) {
$this->measure_unit = $measure_unit;
}
public function getMeasureUnit() {
return $this->measure_unit;
}
public function setStatus($status) {
$this->status = $status;
}
public function getStatus() {
return $this->status;
}
public function setCreated($param) {
$this->created = $param;
return true;
}
public function getCreated() {
return $this->created;
}
public function setModified($param) {
$this->modified = $param;
return true;
}
public function getModified() {
return $this->modified;
}
public function setCategory(Category $category) {
$this->category[] = $category;
}
public function getCategory() {
return $this->category;
}
public function setDetailGroup(DetailGroup $detailGroup) {
$this->detail_group[] = $detailGroup;
}
public function getDetailGroup() {
return $this->detail_group;
}
}
namespace ProductBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use Fresh\Bundle\DoctrineEnumBundle\Validator\Constraints as DoctrineAssert;
/**
* #ORM\Entity
* #ORM\Table(name="detail_group")
*/
class DetailGroup {
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\ManyToOne(targetEntity="DetailGroup")
* #ORM\JoinColumn(name="parent", referencedColumnName="id")
*/
protected $parent;
/**
* #ORM\Column(type="string", length=255)
*/
protected $name;
/**
* #ORM\Column(type="string", length=255)
*/
protected $description;
/**
* #Gedmo\Timestampable(on="create")
* #ORM\Column(name="created", type="datetime")
*/
protected $created;
/**
* #Gedmo\Timestampable(on="update")
* #ORM\Column(name="modified", type="datetime")
*/
protected $modified;
/**
* #ORM\ManyToMany(targetEntity="ProductBundle\Entity\ProductDetail", mappedBy="detail_group", cascade={"all"})
*/
protected $productDetail;
public function __construct() {
$this->productDetail = new \Doctrine\Common\Collections\ArrayCollection();
}
public function getId() {
return $this->id;
}
public function setParent(DetailGroup $parent = null) {
$this->parent = $parent;
}
public function getParent() {
return $this->parent;
}
public function setName($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
public function setDescription($description) {
$this->description = $description;
}
public function getDescription() {
return $this->description;
}
public function setCreated($param) {
$this->created = $param;
return true;
}
public function getCreated() {
return $this->created;
}
public function setModified($param) {
$this->modified = $param;
return true;
}
public function getModified() {
return $this->modified;
}
public function setProductDetail(ProductDetail $productDetail) {
$this->productDetail[] = $productDetail;
}
public function getProductDetail() {
return $this->productDetail;
}
}
This is my ProductDetailType.php form:
<?php
namespace ProductBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class ProductDetailType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
->add('category', 'entity', array('class' => 'CategoryBundle:Category', 'property' => 'name', 'required' => false, 'multiple' => true, 'expanded' => false))
->add('detail_group', 'entity', array('class' => 'ProductBundle:DetailGroup', 'property' => 'name', 'required' => false, 'multiple' => true, 'expanded' => false))
->add('parent', 'entity', array('class' => 'ProductBundle:ProductDetail', 'property' => 'label', 'required' => false))
->add('description', 'text', array('required' => false))
->add('label')
->add('field_type', 'choice', ['choices' => \ProductBundle\DBAL\Types\FieldType::getChoices()])
->add('values_text', 'collection', array('type' => 'text', 'allow_add' => true, 'allow_delete' => true, 'by_reference' => false))
->add('measure_unit', 'text', array('required' => false))
->add('status', 'choice', ['choices' => \ProductBundle\DBAL\Types\StatusType::getChoices()]);
}
public function setDefaultOptions(OptionsResolverInterface $resolver) {
$resolver->setDefaults(array(
'data_class' => 'ProductBundle\Entity\ProductDetail'
));
}
public function getName() {
return 'prod_detail_create';
}
}
And this is my createAction():
/**
* Handle product details creation
*
* #Route("/product_detail/create", name="product_detail_create")
* #Method("POST")
* #Template("ProductBundle:ProductDetail:new.html.twig")
*/
public function createAction(Request $request) {
$entity = new ProductDetail();
$form = $this->createForm(new ProductDetailType(), $entity);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$entity->setValuesText(serialize($form->get('values_text')->getData()));
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('product_detail_list'));
}
return $this->render('ProductBundle:ProductDetail:new.html.twig', array(
'entity' => $entity,
'form' => $form->createView(),
));
}
When I try to insert new records I get this errors:
An exception occurred while executing 'INSERT INTO
product_detail_has_category (category, detail) VALUES (?, ?)' with
params [7, 2]:
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or
update a child row: a foreign key constraint fails
(product_detail_has_category, CONSTRAINT
fk_product_detail_has_category_product_detail1 FOREIGN KEY
(detail) REFERENCES product_detail (id) ON UPDATE CASCADE)
I check the logs and see this:
DEBUG - "START TRANSACTION"
DEBUG - INSERT INTO product_detail (description, label, field_type, values_text, measure_unit, status, created, modified, parent) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
DEBUG - INSERT INTO product_detail_has_category (category, detail) VALUES (?, ?)
DEBUG - "ROLLBACK"
I don't know why it doesn't insert product_detail and the tries to create the relation, what is wrong?
You can either:
set on $category field set cascade={"PERSIST"} in #ManyToMany.
This requires no chnages to controller itself but it depends on whether you like defining cascades.
persist Category object manually before persisting ProductDetail.
$em = ...; // your entity manager
// first, manually persist any category that is found
foreach ( $productDetail->getCategory() as $c ){
$em->persist($c);
}
// then, persist top-level object
$em->persist($productDetail);
// finally, flush everything
$em->flush();
Hope this helps a bit...
I've found where the errors was, see the changes below in annotations:
/**
* #ORM\ManyToMany(targetEntity="CategoryBundle\Entity\Category", inversedBy="pd_detail", cascade={"persist"})
* #ORM\JoinTable(name="product_detail_has_category",
* joinColumns={#ORM\JoinColumn(name="detail", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="category", referencedColumnName="id")}
* )
*/
protected $category;
/**
* #ORM\ManyToMany(targetEntity="ProductBundle\Entity\DetailGroup", inversedBy="productDetail", cascade={"persist"})
* #ORM\JoinTable(name="detail_group_has_product_detail",
* joinColumns={#ORM\JoinColumn(name="detail", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="kgroup", referencedColumnName="id")}
* )
*/
protected $detail_group;
I've inverted the relations in joinColumns and inversedJoinColumns and all works fine, also has to rename group to kgroup due to MySQL query errors!!

Resources