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
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
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
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.
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'
));
}
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!!