Doctrine2 PDO Exception Integrity violation 1048 - Fixtures loading - YML - php

I've the following entity Category defined in YML with bi-directional many-to-many relationship. When i try to load the fixtures data in the corresponding database via doctrine:fixtures:load i receive a PDO Exception error 1048 about integrity violation that the 'name' field can't be null
# src/tuto/JobeetBundle/Resources/config/doctrine/Category.orm.yml
tuto\JobeetBundle\Entity\Category:
type: entity
repositoryClass: tuto\JobeetBundle\Repository\CategoryRepository
table: category
id:
id:
type: integer
generator: { strategy: AUTO }
fields:
name:
type: string
length: 255
unique: true
slug:
type: string
length: 255
unique: true
oneToMany:
jobs:
targetEntity: Job
mappedBy: category
manyToMany:
affiliates:
targetEntity: Affiliate
mappedBy: categories
lifecycleCallbacks:
prePersist: [setSlugValue]
preUpdate: [setSlugValue]
/**
* #var string
*/
private $slug;
public
function setSlug($slug) {
$this - > slug = $slug;
return $this;
}
/**
* Get slug
*
* #return string
*/
public
function getSlug() {
return $this - > slug;
}
/**
* #ORM\PrePersist
* #ORM\PreUpdate
*/
public
function setSlugValue() {
$sl = new Slugify();
$this - > slug = $sl - > slugify($this - > getName());
}
/**
* #ORM\PrePersist
* #ORM\PreUpdate
*/
public
function prePersist() {
$this - > slug = '';
}
May you find the fixture here

You have a typo $qualityManager object on line 20:
Here:
$qualityManager = new Category();
$technician->setName("Quality Manager"); // <-- Wrong object
Try this:
$qualityManager = new Category();
$qualityManager->setName("Quality Manager");
Hope this help

Related

Order (sub-)categories in Doctrine with Symfony2/YML

I've finally succeeded to create a working self-referencing relationship in Doctrine/Symfony2. But, when I request a findAll the table rows aren't returned in the order I want. (Maybe it's not THAT easy, but I can't find any solution anymore.)
The table "categories"
id parentId name
1 NULL music
2 NULL films
3 1 bands
4 1 guitars
5 NULL books
6 2 actors
The file "category.orm.yml"
FormBundle\Entity\Category:
type: entity
oneToMany:
children:
fetch: "EAGER"
targetEntity: FormBundle\Entity\Category
mappedBy: parent
cascade: ["all"]
manyToOne:
parent:
targetEntity: FormBundle\Entity\Category
inversedBy: children
joinColumn:
name: parentId
referencedColumnName: id
table: categories
repositoryClass: FormBundle\Entity\CategoryRepository
id:
id:
column: id
type: integer
id: true
generator:
strategy: AUTO
fields:
name:
type: string
length: '100'
lifecycleCallbacks: { }
I tried an orderBy (in any way I could find, on any field) but I haven't succeeded or had ANY progress with it.
The entity file "Category.php"
<?php
namespace FormBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* Category
*/
class Category
{
/**
* #var integer
*/
private $id;
/**
* #var category
*/
private $parent;
/**
* #var arrayCollection
*/
private $children;
/**
* #var string
*/
private $name;
public function __construct()
{
$this->children = new ArrayCollection();
}
public function getChildren() {
return $this->children;
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set parentId
*
* #param integer $parentId
* #return Category
*/
public function setParent(Category $parent)
{
$this->parent = $parent;
return $this;
}
/**
* Get parentId
*
* #return integer
*/
public function getParent()
{
return $this->parent;
}
/**
* Set name
*
* #param string $name
* #return Category
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
}
What I want as output
<b>music</b>
bands
guitars
<b>films</b>
actors
<b>books</b>
This will be a list, but let's not worry about that right now! It's about the order!
My question
What do I put in my controller to use the relations and fetch the rows in the order I want? Or even better; what do I put in the controller and the repository?
I don't want to use DQL since that is not how Doctrine is meant to be used. I want to learn Doctrine and this is seems to be a very good thing to learn. Yes, I have read the docs for a few days, but nothing seems to work for me. Maybe I overlooked something.
Your tree depth will likely be > 1, Doctrine extensions with his Tree-NestedSet will be a good pick. If it's not the case, your question becomes trivial :
In your controller :
$parentCategories = $categoryRepository->findBy(array('parent' => null));
return $this->render('path_to_your_view.html.twig', array(
'parentCategories' => $parentCategories
));
In your view :
{% for parentCategory in parentCategories %}
<b>{{ parentCategory.getName() | e }}</b>
{% for childCategory in parentCategory.getChildren() %}
<p>{{ childCategory.getName() | e }}</p>
{% endfor %}
{% endfor %}

how to handle manytone relations in a form

im trying to safe the serials from various products already bought, so i made a relation between the invoice table, serials table and my products table, the relations are shown below.
i already made a form to add the relations between the product_table and invoice_table with the serial_table, the form is adding the relations and the serials, but the user shouldn't be available to choose the relations between the tables, it should find the idproduct and id invoice from the purchase made and store the serials and send it to the database without the user changing it, below is the picture of my form.
this is the formtype from the form above
class serialType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('serial','integer')
->add('idPedido')
->add('idProducto')
->add('agregar serial','submit')
;
}
/**
* #param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'sava\InventarioBundle\Entity\TblProductosSeriales'
// 'inherit_data' => true
));
}
/**
* #return string
*/
public function getName()
{
return 'sava_inventariobundle_serial';
}
}
i imported my orm files with the php app/console doctrine:mapping:import command from the tables shown above.
this is my product orm.
sava\InventarioBundle\Entity\TblProductos:
type: entity
table: tbl_productos
fields:
idProduct:
id: true
type: integer
unsigned: false
nullable: false
column: id_product
generator:
strategy: IDENTITY
lifecycleCallbacks: {
}
my serial key table orm.
sava\InventarioBundle\Entity\TblProductosSeriales:
type: entity
table: tbl_productos_seriales
fields:
idProductoSerial:
id: true
type: integer
unsigned: false
nullable: false
column: id_producto_serial
generator:
strategy: IDENTITY
serial:
type: string
length: 80
fixed: false
nullable: false
manyToOne:
idProduct:
targetEntity: TblProductos
cascade: { }
mappedBy: null
inversedBy: null
joinColumns:
id_product:
referencedColumnName: id_product
orphanRemoval: false
idinvoice:
targetEntity: TblPedidos
cascade: { }
mappedBy: null
inversedBy: null
joinColumns:
id_pedido:
referencedColumnName: id_invoice
orphanRemoval: false
lifecycleCallbacks: { }
this is my invoice orm.
sava\InventarioBundle\Entity\TblPedidos:
type: entity
table: tbl_pedidos
fields:
idinvoice:
id: true
type: integer
unsigned: false
nullable: false
column: id_invoice
generator:
strategy: IDENTITY
lifecycleCallbacks: { }
If you don't want the user to be able to choose the relation why are you adding them to the form ? You can set them server side, in the controller :
so :
get the data of your form
query the database with the id from your form to get the two other ones
hydrate the object ( formObject->setStuff($id) )
persist
To give you an idea of what to do : for example if you have a serial and want to get your product id from it
$serial = new Serial;
$form = $this->createForm(new SerialType, $serial);
$request = $this->get('request');
if ($request->getMethod() == 'POST') {
$form->bind($request);
// if form is valid
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
// get the data sent from your form
$data = $form->getData();
$idSerial = $data->getSerial();
// find your ids according to the serial you just got from the form
$repository = $this->getDoctrine()->getManager()->getRepository('AcmeBundleBundle:Products');
$idProduct = $repository->findBySerial($idSerial);
// hydrate the $serial
$serial->setProduct($idProduct);
$em->persist($serial);
$em->flush();
return ....
}
}
if you have the ids in your template do
<form role="form"
action="{{ path('your_route', { 'idProduct': idProduct, 'idInvoice': idInvoice }) }}"
...
</form>
And then you can just get them in your controller like so
UpdateSerialAction($idProduct, $idInvoice)
{
and hydrate the form object with those two arguments

Symfony not finding a custom repository

I have used Symfony's entity generation facilities to create Entities (e.g., Person and Destination) as well as custom Entity Repositories (e.g., PersonRepository and DestinationRepository). The Entities were generated against orm.yml files such as Person.orm.yml and Destination.orm.yml. The DestinationRepository class works great, but my PersonController can never seem to find any methods in the PersonRepository class. The error I'm getting is:
UndefinedMethodException: Attempted to call method "findMe" on class "Me\MyBundle\Entity\Person" in C:\xampp55\htdocs\symtran2\src\Me\MyBundle\Controller\PersonController.php line 124.
I put a little "findMe()" method in the Person entity, and it works, but when I move it to PersonRepository.php, I get the above error. This is driving me crazy, and Google informs me that I'm not the only person to have this problem.
Here is my Destination.org.yml file:
Ginsberg\TransportationBundle\Entity\Destination:
type: entity
repositoryClass: Ginsberg\TransportationBundle\Entity\DestinationRepository
table: destination
id:
id:
type: integer
generator:
strategy: AUTO
fields:
name:
type: string
length: 255
unique: true
nullable: false
is_active:
type: boolean
nullable: true
manyToOne:
program:
targetEntity: Program
inversedBy: destinations
joinColumn:
name: program_id
referencedColumnName: id
oneToMany:
reservations:
targetEntity: Reservation
mappedBy: destination
Here is my Person.orm.yml file:
Ginsberg\TransportationBundle\Entity\Person:
type: entity
repositoryClass: Ginsberg\TransportationBundle\Entity\PersonRepository
table: person
id:
id:
type: integer
generator:
strategy: AUTO
fields:
firstName:
type: string
length: 100
lastName:
type: string
length: 100
uniqname:
type: string
length: 25
unique: true
phone:
type: string
length: 20
nullable: true
status:
type: string
length: 100
nullable: true
dateApproved:
type: datetime
nullable: true
isTermsAgreed:
type: boolean
nullable: true
hasUnpaidTicket:
type: smallint
nullable: true
created:
type: datetime
modified:
type: datetime
nullable: true
oneToMany:
reservations:
targetEntity: Reservation
mappedBy: person
manyToOne:
program:
targetEntity: Program
inversedBy: persons
joinColumn:
name: program_id
referencedColumnName: id
nullable: false
lifecycleCallbacks:
prePersist: [ setCreatedValue ]
preUpdate: [ setModifiedValue ]
Here is my DestinationRepository file:
<?php
namespace Ginsberg\TransportationBundle\Entity;
use Doctrine\ORM\EntityRepository;
/**
* DestinationRepository
*
* This class was generated by the Doctrine ORM. Add your own custom
* repository methods below.
*/
class DestinationRepository extends EntityRepository
{
public function findByProgramsSortedByProgram($param)
{
$dql = 'SELECT d, p FROM GinsbergTransportationBundle:Destination d JOIN d.program p ORDER BY p.name ASC, d.name ASC';
$query = $this->getEntityManager()->createQuery($dql);
try {
return $query->getResult();
} catch (\Doctrine\ORM\NoResultException $ex) {
return null;
}
}
}
And here is my PersonRepository.php file:
<?php
namespace Ginsberg\TransportationBundle\Entity;
use Doctrine\ORM\EntityRepository;
/**
* PersonRepository
*
* This class was generated by the Doctrine ORM. Add your own custom
* repository methods below.
*/
class PersonRepository extends EntityRepository
{
public function findMe() {
print_r("Here");
}
public function findByPendingSortedByCreated($fakeParam)
{
$dql = "SELECT p, prog FROM GinsbergTransportationBundle:Person p JOIN d.program prog WHERE p.status = 'pending' ORDER BY p.created ASC";
$query = getEntityManager()->createQuery($dql);
try {
return $query->getResult();
} catch (\Doctrine\ORM\NoResultException $ex) {
return null;
}
}
}
I'm using YAML for Doctrine but annotations in my controllers.
Here's the controller method that tries to call the findMe() method:
/** Finds and displays a Person entity.
*
* #Route("/{id}", name="person_show")
* #Method("GET")
* #Template()
*/
public function showAction($id)
{
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('GinsbergTransportationBundle:Person')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find Person entity.');
}
$entity->findMe();
//$entity->testMe();
$deleteForm = $this->createDeleteForm($id);
return array(
'entity' => $entity,
'delete_form' => $deleteForm->createView(),
);
}
I would be beyond grateful for any assistance in sorting this out.
you are calling findMe on the entity found by id, you have to call it on the repository
$repository = $em->getRepository('GinsbergTransportationBundle:Person');
$found = $repository->findMe();

Doctrine Extensions Tranlatable with Slugable

When i translate an entity, everything is fine but slug.
My entity:
/**
* #Gedmo\Translatable
* #var string
*/
private $slug;
My Orm.yml
slug:
type: string
length: 1000
nullable: false
gedmo:
translatable: {}
slug:
separator: -
fields:
- title
My ext_translations table:
Title and content successfully translated to given language. Slug is generating over title in posts table. I could not translate slug.
Any idea?
I suggest you to change from Doctrine Extensions to DoctrineBehaviors, because the development of the doctrine extensions has stopped. Also what you want is easily possible with doctrine behaviour:
Your Entity class:
class Entity {
use ORMBehaviors\Translatable\Translatable;
}
Your EntityTranslation class:
class EntityTranslation {
use ORMBehaviors\Translatable\Translation;
use ORMBehaviors\Sluggable\Sluggable;
/**
* #var string
* #ORM\Column(type="text", nullable=true)
*/
protected $title;
public function getSluggableFields()
{
return [ 'title' ];
}
}

Mapping issue Doctrine & Symfony

I have 3 entities where the mapping is causing some issues.
The two problems im facing are:
When i use doctrine command line schema update, it removes the column "item_type" in the item_type_field table. It looks like doctrine is not seeing this column in the YML file, while it is there.
In the Symfony application the mapping between TypeField and FieldType is not working. When i dump the FieldType of a field it returns null.
Am i missing something?
Entities and mappings:
class ItemType
{
protected $id;
protected $title;
protected $description;
protected $fields;
public function __construct(){
$this->fields = new ArrayCollection();
}
public function getId()
{
return $this->id;
}
public function setTitle($title)
{
$this->title = $title;
return $this;
}
public function getTitle()
{
return $this->title;
}
public function setDescription($description)
{
$this->description = $description;
return $this;
}
public function getDescription()
{
return $this->description;
}
public function addField(\Aveqcms\CoreBundle\Entity\TypeField $field)
{
$field->setItemType($this);
$this->fields[] = $field;
return $this;
}
public function removeField(\Aveqcms\CoreBundle\Entity\TypeField $field)
{
$this->fields->removeElement($field);
}
public function getFields()
{
return $this->fields;
}
}
class TypeField
{
private $id;
private $item_type;
private $field_type;
public function getId()
{
return $this->id;
}
public function setItemType($itemType)
{
$this->item_type = $itemType;
return $this;
}
public function getItemType()
{
return $this->item_type;
}
public function setFieldType($fieldType)
{
$this->field_type = $fieldType;
return $this;
}
public function getFieldType()
{
return $this->field_type;
}
}
class FieldType
{
private $id;
private $title;
private $fields;
public function __construct()
{
$this->fields = new ArrayCollection();
}
public function getId()
{
return $this->id;
}
public function setTitle($title)
{
$this->title = $title;
return $this;
}
public function getTitle()
{
return $this->title;
}
}
Mapping files:
Acme\CoreBundle\Entity\ItemType:
type: entity
table: item_type
id:
id:
type: integer
generator: { strategy: AUTO }
fields:
title:
type: string
length: 255
description:
type: string
length: 255
oneToMany:
fields:
targetEntity: TypeField
mappedBy: item_type
cascade: [persist]
Acme\CoreBundle\Entity\TypeField:
type: entity
table: item_type_field
id:
id:
type: integer
generator: { strategy: AUTO }
manyToOne:
field_type:
targetEntity: FieldType
inversedBy: fields
joinColumn:
name: field_type
referencedColumnName: id
manyToOne:
item_type:
targetEntity: ItemType
inversedBy: fields
joinColumn:
name: item_type
referencedColumnName: id
Acme\CoreBundle\Entity\FieldType:
type: entity
table: field_type
id:
id:
type: integer
id: true
generator:
strategy: AUTO
fields:
title:
type: text
oneToMany:
fields:
targetEntity: TypeField
mappedBy: field_type
In TypeField you have manyToOne repeated twice. The second one overrides the first one whcih is why doctrine is not seeing it.
Acme\CoreBundle\Entity\TypeField:
type: entity
table: item_type_field
id:
id:
type: integer
generator: { strategy: AUTO }
manyToOne:
field_type:
targetEntity: FieldType
inversedBy: fields
joinColumn:
name: field_type
referencedColumnName: id
#manyToOne: *** Get rid of this ***
item_type:
targetEntity: ItemType
inversedBy: fields
joinColumn:
name: item_type
referencedColumnName: id
This may or may not fix all your issues. And it certainly does not address the issue of your very confusing naming conventions.

Categories