Symfony2.7 field validates twice, using validation-groups and UniqueEntity - symfony-forms

Field gets validated twice, causing 2 DB calls and 2 of the same error message.
I have Subscriber class the main User, Registration class and RegistrationType which embeds SubscriberType as tutorial How to Implement a simple Registration Form suggests. The main username field has constraint of UniqueEntity, and any time a non-unique username is entered the "username already exists" error message pops up twice, checking the log DB call to check for existing username is called twice. I've googled this and have not found a same case as mine, but have found similar cases. I have no idea what to do here.
The database is legacy so I couldn't just switch to FOSUserBundle, and the reason I don't use # annotations but instead use *.orm.yml and validation.yml
class RegistrationType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
if(!$options['service']){
$builder->add('user', new SubscriberType());
$builder->add('Register', 'submit');
} else {
$subscriber = new Subscriber();
$subscriber->setEmail($options['user_information']->getEmail());
$subscriber->setFirstname($options['user_information']->getFirstname());
$subscriber->setLastname($options['user_information']->getLastname());
$subscriber->setUsername($options['user_information']->getEmail());
switch($options['service']){
case 'facebook':
$subscriber->setFbEmail($options['user_information']->getEmail());
break;
}
$builder->add('user', new SubscriberType($subscriber), array('service' => $options['service'],
'user_information' => $options['user_information'], 'data'=> $subscriber));
}
$builder->add(
'terms',
'checkbox',
array('property_path' => 'termsAccepted')
);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'service' => false,
'user_information' => false
,'validation_groups' => array('Default', 'registration')
));
}
public function getName()
{
return 'registration';
}
}
the custom 'service' options is to integrate HWIOAuthBundle, whole other story there.
class SubscriberType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
if(!$options['service']){
$builder->add('username', 'email');
$builder->add('plainPassword', 'repeated', array(
'first_name' => 'password',
'second_name' => 'confirm',
'type' => 'password',
));
} else {
$builder->add('email', 'text', array('read_only' => true, ));
$builder->add('firstname', 'text');
$builder->add('lastname', 'text');
$builder->add('username', 'hidden');
$builder->add('fbEmail', 'hidden');
$builder->add('gplusEmail', 'hidden');
}
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Subscriber',
'service' => false,
'user_information' => false
,'validation_groups' => array('Default', 'registration')
));
}
/* DEPRECATED since 2.7
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Subscriber',
'service' => false,
'user_information' => false
));
}
*/
public function getName()
{
return 'subscriber';
}
}
Registration.php:
<?php
// src/AppBundle/Form/Model/Registration
namespace AppBundle\Form\Model;
use Symfony\Component\Validator\Constraints as Assert;
use AppBundle\Entity\Subscriber;
class Registration
{
/**
* #Assert\Type(type="AppBundle\Entity\Subscriber")
* #Assert\Valid()
*/
protected $user;
/**
* #Assert\NotBlank()
* #Assert\True()
*/
protected $termsAccepted;
public function setUser(Subscriber $user)
{
$this->user = $user;
}
public function getUser()
{
return $this->user;
}
public function getTermsAccepted()
{
return $this->termsAccepted;
}
public function setTermsAccepted($termsAccepted)
{
$this->termsAccepted = (bool) $termsAccepted;
}
}
Subscriber.php //Entity:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\UserInterface;
use Doctrine\Common\Collections\ArrayCollection;
//use FOS\UserBundle\Entity\User as BaseUser;
/**
* Subscriber
*/
class Subscriber implements UserInterface, \Serializable
{
/**
* #var integer
*/
private $id;
/**
* #var string
*/
private $username;
/**
* #var string
*/
private $email;
/**
* #var string
*/
private $gplusEmail;
/**
* #var string
*/
private $fbEmail;
/**
* #var string
*/
private $sha1Password;
/**
* #var string
*/
private $salt;
/**
* #var float
*/
private $unit;
/**
* #var string
*/
private $validate;
/**
* #var string
*/
private $rememberKey;
/**
* #var string
*/
private $firstname = '';
/**
* #var string
*/
private $lastname = '';
/**
* #var string
*/
private $avatar = '';
/**
* #var string
*/
private $countryId = '';
/**
* #var string
*/
private $address;
/**
* #var string
*/
private $phone;
/**
* #var string
*/
private $gender = '';
/**
* #var \DateTime
*/
private $birthdate;
/**
* #var \DateTime
*/
private $lastAttemp;
/**
* #var integer
*/
private $attempCount;
/**
* #var \DateTime
*/
private $lastloginDate;
/**
* #var \DateTime
*/
private $createdAt;
/**
* #var \DateTime
*/
private $updatedAt;
/**
* #var \Doctrine\Common\Collections\Collection
*/
private $groups;
/**
* #ORM\Column(type="string", length=255)
*/
protected $plainPassword;
/**
* Constructor
*/
public function __construct()
{
$this->groups = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set username
*
* #param string $username
* #return Subscriber
*/
public function setUsername($username)
{
$this->username = $username;
return $this;
}
/**
* Get username
*
* #return string
*/
public function getUsername()
{
return $this->username;
}
/**
* Set email
*
* #param string $email
* #return Subscriber
*/
public function setEmail($email)
{
$this->email = $email;
return $this;
}
/**
* Get email
*
* #return string
*/
public function getEmail()
{
return $this->email;
}
/**
* Set gplusEmail
*
* #param string $gplusEmail
* #return Subscriber
*/
public function setGplusEmail($gplusEmail)
{
$this->gplusEmail = $gplusEmail;
return $this;
}
/**
* Get gplusEmail
*
* #return string
*/
public function getGplusEmail()
{
return $this->gplusEmail;
}
/**
* Set fbEmail
*
* #param string $fbEmail
* #return Subscriber
*/
public function setFbEmail($fbEmail)
{
$this->fbEmail = $fbEmail;
return $this;
}
/**
* Get fbEmail
*
* #return string
*/
public function getFbEmail()
{
return $this->fbEmail;
}
/**
* Set sha1Password
*
* #param string $sha1Password
* #return Subscriber
*/
public function setSha1Password($sha1Password)
{
$this->sha1Password = $sha1Password;
return $this;
}
/**
* Get sha1Password
*
* #return string
*/
public function getSha1Password()
{
return $this->sha1Password;
}
/**
* Set salt
*
* #param string $salt
* #return Subscriber
*/
public function setSalt($salt)
{
$this->salt = $salt;
return $this;
}
/**
* Get salt
*
* #return string
*/
public function getSalt()
{
return $this->salt;
}
/**
* Set unit
*
* #param float $unit
* #return Subscriber
*/
public function setUnit($unit)
{
$this->unit = $unit;
return $this;
}
/**
* Get unit
*
* #return float
*/
public function getUnit()
{
return $this->unit;
}
/**
* Set validate
*
* #param string $validate
* #return Subscriber
*/
public function setValidate($validate)
{
$this->validate = $validate;
return $this;
}
/**
* Get validate
*
* #return string
*/
public function getValidate()
{
return $this->validate;
}
/**
* Set rememberKey
*
* #param string $rememberKey
* #return Subscriber
*/
public function setRememberKey($rememberKey)
{
$this->rememberKey = $rememberKey;
return $this;
}
/**
* Get rememberKey
*
* #return string
*/
public function getRememberKey()
{
return $this->rememberKey;
}
/**
* Set firstname
*
* #param string $firstname
* #return Subscriber
*/
public function setFirstname($firstname)
{
$this->firstname = $firstname;
return $this;
}
/**
* Get firstname
*
* #return string
*/
public function getFirstname()
{
return $this->firstname;
}
/**
* Set lastname
*
* #param string $lastname
* #return Subscriber
*/
public function setLastname($lastname)
{
$this->lastname = $lastname;
return $this;
}
/**
* Get lastname
*
* #return string
*/
public function getLastname()
{
return $this->lastname;
}
/**
* Set avatar
*
* #param string $avatar
* #return Subscriber
*/
public function setAvatar($avatar)
{
$this->avatar = $avatar;
return $this;
}
/**
* Get avatar
*
* #return string
*/
public function getAvatar()
{
return $this->avatar;
}
/**
* Set countryId
*
* #param string $countryId
* #return Subscriber
*/
public function setCountryId($countryId)
{
$this->countryId = $countryId;
return $this;
}
/**
* Get countryId
*
* #return string
*/
public function getCountryId()
{
return $this->countryId;
}
/**
* Set address
*
* #param string $address
* #return Subscriber
*/
public function setAddress($address)
{
$this->address = $address;
return $this;
}
/**
* Get address
*
* #return string
*/
public function getAddress()
{
return $this->address;
}
/**
* Set phone
*
* #param string $phone
* #return Subscriber
*/
public function setPhone($phone)
{
$this->phone = $phone;
return $this;
}
/**
* Get phone
*
* #return string
*/
public function getPhone()
{
return $this->phone;
}
/**
* Set gender
*
* #param string $gender
* #return Subscriber
*/
public function setGender($gender)
{
$this->gender = $gender;
return $this;
}
/**
* Get gender
*
* #return string
*/
public function getGender()
{
return $this->gender;
}
/**
* Set birthdate
*
* #param \DateTime $birthdate
* #return Subscriber
*/
public function setBirthdate($birthdate)
{
$this->birthdate = $birthdate;
return $this;
}
/**
* Get birthdate
*
* #return \DateTime
*/
public function getBirthdate()
{
return $this->birthdate;
}
/**
* Set lastAttemp
*
* #param \DateTime $lastAttemp
* #return Subscriber
*/
public function setLastAttemp($lastAttemp)
{
$this->lastAttemp = $lastAttemp;
return $this;
}
/**
* Get lastAttemp
*
* #return \DateTime
*/
public function getLastAttemp()
{
return $this->lastAttemp;
}
/**
* Set attempCount
*
* #param integer $attempCount
* #return Subscriber
*/
public function setAttempCount($attempCount)
{
$this->attempCount = $attempCount;
return $this;
}
/**
* Get attempCount
*
* #return integer
*/
public function getAttempCount()
{
return $this->attempCount;
}
/**
* Set lastloginDate
*
* #param \DateTime $lastloginDate
* #return Subscriber
*/
public function setLastloginDate($lastloginDate)
{
$this->lastloginDate = $lastloginDate;
return $this;
}
/**
* Get lastloginDate
*
* #return \DateTime
*/
public function getLastloginDate()
{
return $this->lastloginDate;
}
/**
* Set createdAt
*
* #param \DateTime $createdAt
* #return Subscriber
*/
public function setCreatedAt($createdAt)
{
$this->createdAt = $createdAt;
return $this;
}
/**
* Get createdAt
*
* #return \DateTime
*/
public function getCreatedAt()
{
return $this->createdAt;
}
/**
* Set updatedAt
*
* #param \DateTime $updatedAt
* #return Subscriber
*/
public function setUpdatedAt($updatedAt)
{
$this->updatedAt = $updatedAt;
return $this;
}
/**
* Get updatedAt
*
* #return \DateTime
*/
public function getUpdatedAt()
{
return $this->updatedAt;
}
/**
* Add groups
*
* #param \AppBundle\Entity\SubscriberGroup $groups
* #return Subscriber
*/
public function addGroup(\AppBundle\Entity\SubscriberGroup $groups)
{
$this->groups[] = $groups;
return $this;
}
/**
* Remove groups
*
* #param \AppBundle\Entity\SubscriberGroup $groups
*/
public function removeGroup(\AppBundle\Entity\SubscriberGroup $groups)
{
$this->groups->removeElement($groups);
}
/**
* Get groups
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getGroups()
{
return $this->groups;
}
/**
* Get setPassword
*
* #param string
*/
public function setPassword($hashed_password)
{
return $this->setSha1Password($hashed_password);
}
/**
* Get setPassword
*
* #return string
*/
public function getPassword()
{
return $this->sha1Password;
}
///*
public function serialize()
{
return serialize(array(
$this->id,
$this->username,
$this->sha1Password,
$this->salt
));
}
///*
public function unserialize($serialized)
{
list (
$this->id,
$this->username,
$this->sha1Password,
$this->salt
) = unserialize($serialized);
}
//*/
public function getRoles()
{
$roles = array();
//var_dump($this->getGroups());
foreach($this->getGroups() as $group){
$roles[] = $group->getRole();
}
$roles[] = "ROLE_SUBSCRIBER";
return array_unique($roles);
}
public function eraseCredentials()
{
}
public function getPlainPassword()
{
return $this->plainPassword;
}
public function setPlainPassword($password)
{
$this->plainPassword = $password;
}
}
And Subscriber.orm.yml as follows:
AppBundle\Entity\Subscriber:
type: entity
table: w_subscriber
repositoryClass: AppBundle\Entity\SubscriberRepository
id:
id:
type: bigint
nullable: false
unsigned: false
comment: ''
id: true
generator:
strategy: IDENTITY
fields:
username:
type: string
nullable: false
length: 50
fixed: false
comment: ''
email:
type: string
nullable: false
length: 150
fixed: false
comment: ''
gplusEmail:
type: string
nullable: true
length: 150
fixed: false
comment: ''
column: gplus_email
fbEmail:
type: string
nullable: true
length: 150
fixed: false
comment: ''
column: fb_email
sha1Password:
type: string
nullable: true
length: 40
fixed: false
comment: ''
column: sha1_password
salt:
type: string
nullable: true
length: 32
fixed: false
comment: ''
unit:
type: float
nullable: true
precision: 18
scale: 2
comment: ''
default: '0.00'
validate:
type: string
nullable: true
length: 10
fixed: false
comment: ''
rememberKey:
type: string
nullable: true
length: 50
fixed: false
comment: ''
column: remember_key
firstname:
type: string
nullable: false
length: 200
fixed: false
comment: ''
lastname:
type: string
nullable: true
length: 200
fixed: false
comment: ''
avatar:
type: string
nullable: false
length: 200
fixed: false
comment: ''
countryId:
type: string
nullable: false
length: 5
fixed: false
comment: ''
default: MN
column: country_id
address:
type: text
nullable: true
length: null
fixed: false
comment: ''
phone:
type: string
nullable: true
length: 50
fixed: false
comment: ''
gender:
type: string
nullable: false
length: 1
fixed: false
comment: ''
default: M
birthdate:
type: date
nullable: true
comment: ''
lastAttemp:
type: datetime
nullable: true
comment: ''
column: last_attemp
attempCount:
type: bigint
nullable: true
unsigned: false
comment: ''
default: '0'
column: attemp_count
lastloginDate:
type: datetime
nullable: true
comment: ''
column: lastlogin_date
createdAt:
type: datetime
nullable: false
comment: ''
column: created_at
gedmo:
timestampable:
on: create
updatedAt:
type: datetime
nullable: false
comment: ''
column: updated_at
gedmo:
timestampable:
on: update
lifecycleCallbacks: { }
manyToMany:
groups:
targetEntity: SubscriberGroup
joinTable:
name: w_subscriber_credential
joinColumns:
subscriber_id:
referencedColumnName: id
inverseJoinColumns:
group_id:
referencedColumnName: id
and finally validation.yml
# src/AppBundle/Resources/config/validation.yml
AppBundle\Entity\Subscriber:
constraints:
- \Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity:
fields: [ username ]
groups: [ registration ]
message: 'this email is already registered'
properties:
email:
- Email: ~
the controller:
<?php
// src/AppBundle/Controller/SecurityController.php
namespace AppBundle\Controller;
use Symfony\Component\HttpFoundation\Request;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use AppBundle\Form\Type\RegistrationType;
use AppBundle\Form\Model\Registration;
class SecurityController extends Controller
{
/**
* #Route("/register", name="register")
*/
public function registerAction()
{
$form = $this->createForm(new RegistrationType(), new Registration(), array(
'action' => $this->generateUrl('register_create'),
));
return $this->render(
'security/register.html.twig',
array('form' => $form->createView())
);
}
/**
* #Route("/register/create", name="register_create")
*/
public function createAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
$form = $this->createForm(new RegistrationType(), new Registration());
$form->handleRequest($request);
if ($form->isValid()) {
$registration = $form->getData();
$user = $registration->getUser();
$user->setEmail($user->getUsername());
$this->get('my.oauth_aware.user_provider.service')->setUserPassword($user, $user->getPlainPassword());
$em->persist($registration->getUser());
$em->flush();
//return $this->redirectToRoute('homepage');
}
return $this->render(
'security/register.html.twig',
array('form' => $form->createView())
);
}
/**
* #Route("/login_check", name="login_check")
*/
public function loginCheckAction()
{
// this controller will not be executed,
// as the route is handled by the Security system
}
}
note that username is also the email field, I have not posted the template because it is also rather large, and I believe it has nothing to do with validation, but if anyone wants to see it I would gladly post it.
also among the configurations there is
config.yml->framework->validation->enable_annotations->true

I'm sorry for wasting everyone's time. The error was in Declaration of the main AppBundle, or actually having declarations of 2 differnet bundle within 1 bundle file hierarchy.
To override HWIOAuthBundle's templates and controllers, I declared a new bundle within AppBundle, for some reason I thought that a new declaration was required. Silly me.
So symfony loaded validation.yml twice foreach separate declarations of bundles.
By moving getParent function into AppBundle declaration, and removing 2nd Bundle class declaration and its initialization from AppKernel solves the problem.

Related

API platform cannot post relationship id

I am quite new to API platform and currently, I am trying to map with entities. I have one entity called "User" entity and another one is called "Credit" entity. And their relationship with each other is "One-To-One" relationship. What I want to achieve is whenever I call from User post and update , I can modify credit and vise vasa. Currently, I
can update credit entity from User "PUT" as shown below. When I set "amount" of the credit entity, it will nicely store with user_id inside credit table.
But when I try from credit entity, I cannot add in the userId, instead it only accepts the amount.
This is my User Entity
<?php
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Validator\Constraints as Assert;
use Gedmo\Mapping\Annotation as Gedmo;
use Fresh\VichUploaderSerializationBundle\Annotation as Fresh;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
/**
* #ApiResource(
* collectionOperations={
* "get" = {
* "access_control"="is_granted('ROLE_API')"
* },
* "post" ={
* "route_name"="api_users_post_collection"
* },
* "app_login"={
* "access_control"="is_granted('ROLE_API')",
* "route_name"="app_login",
* "method"="POST",
* "swagger_context" = {
* "parameters" = {
* {
* "name" = "User Login",
* "in" = "body",
* "type" = "object",
* "schema"= {
* "email" = {"type": "string"},
* "password" = {"type" : "string"},
* "example" ={
* "email" = "string",
* "password" ="string"
* }
* }
* }
* },
* "responses" = {
* "200" = {
* "description" = "You will get User IRI and PHPSESSID",
* "schema" = {
* "type" = "object",
* "required" = {
* "email",
* "password"
* },
* "properties" = {
* "user" = {
* "type" = "string"
* },
* "PHPSESSID" = {
* "type" = "string"
* },
*
* }
* }
* },
* "400" = {
* "description" = "Bad Requests"
* }
* },
* "summary" = "User Login",
* "description" = "Set User session to api platform by email and password",
* "consumes" = {
* "application/json",
* "text/html",
* },
* "produces" = {
* "application/json",
* "application/ld+json"
* }
* }
* }
* },
* itemOperations={
* "get" ={
* "access_control"="is_granted('ROLE_API')"
* },
* "put" = {
* "access_control"="is_granted('ROLE_API')"
* }
* },
* normalizationContext={
* "groups"={"user:read"},"swagger_definition_name"="Read"
* },
* denormalizationContext={
* "groups"={"user:write"},"swagger_definition_name"="Write"
* },
* shortName="User"
*
* )
* #UniqueEntity(fields={"email"})
* #UniqueEntity(fields={"contact"})
* #ORM\Entity(repositoryClass="App\Repository\UserRepository")
* #Vich\Uploadable
*
* #Fresh\VichSerializableClass
*/
class User implements UserInterface
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=180, unique=true)
* #Groups({"user:read", "user:write", "credit:item:get", "credit:write"})
* #Assert\Email()
* #Assert\NotBlank()
*/
private $email;
/**
* #ORM\Column(type="json")
*/
private $roles = [];
/**
* #var string The hashed password
* #ORM\Column(type="string")
* #Groups({"user:write"})
* #Assert\NotBlank()
*/
private $password;
/**
* #ORM\Column(type="string", length=255)
* #Groups({"user:read", "user:write"})
* #Assert\NotBlank()
*/
private $firstName;
/**
* #ORM\Column(type="string", length=255)
* #Groups({"user:read", "user:write"})
* #Assert\NotBlank()
*/
private $lastName;
/**
* #var string provide in YYYY-MM-DD (neglect Time)
* #ORM\Column(type="date")
* #Groups({"user:read", "user:write"})
* #Assert\NotBlank()
*/
private $dob;
/**
* #ORM\Column(type="text")
* #Groups({"user:read", "user:write"})
* #Assert\NotBlank()
*/
private $address;
/**
* #ORM\Column(type="string", length=255)
* #Groups({"user:read", "user:write"})
* #Assert\NotBlank()
* #Assert\Length(
* min=8,
* max=8,
* maxMessage="contact number must have 8 character",
* minMessage="contact number must have 8 character"
* )
*/
private $contact;
/**
* #ORM\OneToOne(targetEntity="App\Entity\Credit", mappedBy="user_id", cascade={"persist"}, orphanRemoval=true)
* #Groups({"user:read", "user:write"})
* #Assert\Valid()
*/
private $credit;
/**
* #var \DateTime $created
*
* #Gedmo\Timestampable(on="create")
* #ORM\Column(type="datetime")
*/
private $created_at;
/**
* #var \DateTime $updated
*
* #Gedmo\Timestampable(on="update")
* #ORM\Column(type="datetime")
*/
private $updated_at;
public function getId(): ?int
{
return $this->id;
}
public function getEmail(): ?string
{
return $this->email;
}
public function setEmail(string $email): self
{
$this->email = $email;
return $this;
}
/**
* A visual identifier that represents this user.
*
* #see UserInterface
*/
public function getUsername(): string
{
return (string) $this->email;
}
/**
* #see UserInterface
*/
public function getRoles(): array
{
$roles = $this->roles;
// guarantee every user at least has ROLE_USER
$roles[] = 'ROLE_USER';
return array_unique($roles);
}
public function setRoles(array $roles): self
{
$this->roles = $roles;
return $this;
}
/**
* #see UserInterface
*/
public function getPassword(): string
{
return (string) $this->password;
}
public function setPassword(string $password): self
{
$this->password = $password;
return $this;
}
/**
* #see UserInterface
*/
public function getSalt()
{
// not needed when using the "bcrypt" algorithm in security.yaml
}
/**
* #see UserInterface
*/
public function eraseCredentials()
{
// If you store any temporary, sensitive data on the user, clear it here
// $this->plainPassword = null;
}
public function getFirstName(): ?string
{
return $this->firstName;
}
public function setFirstName(string $firstName): self
{
$this->firstName = $firstName;
return $this;
}
public function getLastName(): ?string
{
return $this->lastName;
}
public function setLastName(string $lastName): self
{
$this->lastName = $lastName;
return $this;
}
public function getDob(): ?\DateTimeInterface
{
return $this->dob;
}
public function setDob(\DateTimeInterface $dob): self
{
$this->dob = $dob;
return $this;
}
public function getAddress(): ?string
{
return $this->address;
}
public function setAddress(string $address): self
{
$this->address = $address;
return $this;
}
public function getContact(): ?string
{
return $this->contact;
}
public function setContact(string $contact): self
{
$this->contact = $contact;
return $this;
}
public function getCredit(): ?Credit
{
return $this->credit;
}
public function setCredit(?Credit $credit): self
{
$this->credit = $credit;
// set (or unset) the owning side of the relation if necessary
$newUser_id = $credit === null ? null : $this;
if ($newUser_id !== $credit->getUserId()) {
$credit->setUserId($newUser_id);
}
return $this;
}
public function getCreated()
{
return $this->created_at;
}
public function getUpdated()
{
return $this->updated_at;
}
}
This is my Credit Entity
<?php
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Validator\Constraints as Assert;
/**
* #ApiResource(
* collectionOperations={
* "get",
* "post"
* },
* itemOperations={
* "get" = {
* "normalization_context"={"groups"={"credit:read", "credit:item:get"}},
* },
* "put"
* },
* shortName="credit",
* normalizationContext={"groups"={"credit:read"}, "swagger_definition_name"="Read"},
* denormalizationContext={"groups"={"credit:write"}, "swagger_definition_name"="Write"},
* )
* #ORM\Entity(repositoryClass="App\Repository\CreditRepository")
*/
class Credit
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=255)
* #Groups({"credit:read", "credit:write", "user:read", "user:write"})
*/
private $amount;
/**
* #ORM\OneToOne(targetEntity="App\Entity\User", inversedBy="credit")
* #Groups({"credit:read", "credit:write"})
* #ORM\JoinColumn(nullable=false)
* #Assert\Valid()
*/
private $user_id;
/**
* #var \DateTime $created
*
* #Gedmo\Timestampable(on="create")
* #ORM\Column(type="datetime")
*/
private $created_at;
/**
* #var \DateTime $updated
*
* #Gedmo\Timestampable(on="update")
* #ORM\Column(type="datetime")
*/
private $updated_at;
public function getId(): ?int
{
return $this->id;
}
public function getAmount(): ?string
{
return $this->amount;
}
public function setAmount(string $amount): self
{
$this->amount = $amount;
return $this;
}
public function getUserId(): ?User
{
return $this->user_id;
}
public function setUserId(?User $user_id): self
{
$this->user_id = $user_id;
return $this;
}
public function getCreated()
{
return $this->created_at;
}
public function getUpdated()
{
return $this->updated_at;
}
}
How can I achieve that when i call credit entity, i can add in user_id (which is the owner of the credit) ?

symfony3 CollectionType OneToMany

I have 2 entities: person and emailaddress
class Person
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* #var Emailaddress[]
* #ORM\OneToMany(targetEntity="Emailaddress", mappedBy="person", cascade={"ALL"})
*
*/
private $emails;
public function __construct() {
$this->emails = new ArrayCollection();
}
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
*
* #return Person
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Add email
*
* #param \AppBundle\Entity\Emailaddress $email
*
* #return Person
*/
public function addEmail(\AppBundle\Entity\Emailaddress $email)
{
$this->emails[] = $email;
$email->setPerson($this);
return $this;
}
/**
* Remove email
*
* #param \AppBundle\Entity\Emailaddress $email
*/
public function removeEmail(\AppBundle\Entity\Emailaddress $email)
{
$this->emails->removeElement($email);
}
/**
* Get emails
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getEmails()
{
return $this->emails;
}
}
class Emailaddress
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="emailaddress", type="string", length=100)
*/
private $emailaddress;
/**
* #var Person
* #ORM\ManyToOne(targetEntity="Person", inversedBy="emails")
* #ORM\JoinColumn(name="person_id", referencedColumnName="id")
*/
private $person;
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set emailaddress
*
* #param string $emailaddress
*
* #return Emailaddress
*/
public function setEmailaddress($emailaddress)
{
$this->emailaddress = $emailaddress;
return $this;
}
/**
* Get emailaddress
*
* #return string
*/
public function getEmailaddress()
{
return $this->emailaddress;
}
/**
* Set person
*
* #param \AppBundle\Entity\Person $person
*
* #return Emailaddress
*/
public function setPerson(\AppBundle\Entity\Person $person = null)
{
$this->person = $person;
return $this;
}
/**
* Get person
*
* #return \AppBundle\Entity\Person
*/
public function getPerson()
{
return $this->person;
}
}
In EmailaddressType I have:
$builder->add('email');
And in PersonType:
$builder->add('name')
->add('emails', CollectionType::class, array(
'entry_type' => EmailAddressType::class,
'allow_add' => true,
));
Now when the form is generated on the emails field does not display anything.
How can I generate email fields?
Thanks

BjyAuthorize configuration for resources

I configured my BjyAuthorised using SamUser and other resources online. I thought the following configuration suppose to block all users but 'admin'. However, role of a user does not affect the result. Any user can access this resource. Please help.
My BjyAuthorise config file:
<?php
return array(
'bjyauthorize' => array(
'default_role' => 'guest',
'resource_providers' => array(
'BjyAuthorize\Provider\Resource\Config' => array(
'OnlineFieldEvaluation\Controller\OnlineFieldEvaluation' => array(),
),
),
'rule_providers' => array(
'BjyAuthorize\Provider\Rule\Config' => array(
'allow' => array(
array(array('admin'), 'OnlineFieldEvaluation\Controller\OnlineFieldEvaluation', array('index')),
),
),
),
'identity_provider' => 'BjyAuthorize\Provider\Identity\AuthenticationIdentityProvider',
'BjyAuthorize\Provider\Role\ObjectRepositoryProvider' => array(
'object_manager' => 'doctrine.entity_manager.orm_default',
'role_entity_class' => 'Application\Entity\Role',
),
),
// 'guards' => array(
// 'BjyAuthorize\Guard\Controller' => array(
// array('controller' => 'OnlineFieldEvaluation\Controller\OnlineFieldEvaluation',
// 'action' => array('index'),
// 'roles' => array('admin')),
// ),
// ),
);
Module config file
<?php
namespace OnlineFieldEvaluation;
return array(
'controllers' => array(
'invokables' => array(
'OnlineFieldEvaluation\Controller\OnlineFieldEvaluation' => 'OnlineFieldEvaluation\Controller\OnlineFieldEvaluationController',
),
),
// The following section is new and should be added to your file
'router' => array(
'routes' => array(
'OnlineFieldEvaluation' => array(
'type' => 'segment',
'options' => array(
'route' => '/onlinefieldevaluation[/][:action][/:id]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
),
'defaults' => array(
'controller' => 'OnlineFieldEvaluation\Controller\OnlineFieldEvaluation',
'action' => 'index',
),
),
),
),
),
'view_manager' => array(
'template_path_stack' => array(
'OnlineFieldEvaluation' => __DIR__ . '/../view',
),
),
// Doctrine config
'doctrine' => array(
'driver' => array(
__NAMESPACE__ . '_driver' => array(
'class' => 'Doctrine\ORM\Mapping\Driver\AnnotationDriver',
'cache' => 'array',
'paths' => array(__DIR__ . '/../src/' . __NAMESPACE__ . '/Entity')
),
'orm_default' => array(
'drivers' => array(
__NAMESPACE__ . '\Entity' => __NAMESPACE__ . '_driver'
)
),
),
),
);
Systemuser class
<?php
namespace Application\Entity;
use BjyAuthorize\Provider\Role\ProviderInterface;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use ZfcUser\Entity\UserInterface;
/**
* Systemuser
*
* #ORM\Table(name="systemuser",uniqueConstraints={#ORM\UniqueConstraint(name="email_idx", columns={"email"})})
* #ORM\Entity
* ORM\Entity(repositoryClass="Application\Entity\Repository\SystemuserRepository")
*/
class Systemuser implements UserInterface, ProviderInterface {
/**
* #var int
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="email", type="string", length=100, nullable=false)
*/
private $email;
/**
* #var string
* #ORM\Column(name="displayname", type="string", length=50, nullable=true)
*/
protected $displayName;
/**
* #var string
*
* #ORM\Column(name="username", type="string", length=100, nullable=true)
*/
private $username;
/**
* #var string
*
* #ORM\Column(name="password", type="string", length=64, nullable=false)
*/
private $password;
/**
* #var string $country
*
* #ORM\Column(type="string", length=255, nullable=true)
*/
private $country;
/**
* var \Application\Entity\Role
*
* ORM\ManyToOne(targetEntity="Application\Entity\Role")
* ORM\JoinColumns({
* ORM\JoinColumn(name="role_id", referencedColumnName="id",nullable=true)
* })
*/
//private $role;
/**
* #var \Doctrine\Common\Collections\Collection
* #ORM\ManyToMany(targetEntity="Application\Entity\Role")
* #ORM\JoinTable(name="users_roles",
* joinColumns={#ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="role_id", referencedColumnName="id")}
* )
*/
protected $roles;
/**
* Initialies the roles variable.
*/
public function __construct()
{
$this->roles = new ArrayCollection();
}
/**
* Get role.
*
* #return array
*/
public function getRoles()
{
return $this->roles->getValues();
}
/**
* Add a role to the user.
*
* #param Role $role
*
* #return void
*/
public function addRole($role)
{
$this->roles[] = $role;
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set id.
*
* #param int $id
* #return UserInterface
*/
public function setId($id) {
$this->id = $id;
}
/**
* Set email
*
* #param string $email
* #return Systemuser
*/
public function setEmail($email)
{
$this->email = $email;
return $this;
}
/**
* Get email
*
* #return string
*/
public function getEmail()
{
return $this->email;
}
/**
* Set username
*
* #param string $username
* #return Systemuser
*/
public function setUsername($username)
{
$this->username = $username;
return $this;
}
/**
* Get username
*
* #return string
*/
public function getUsername()
{
return $this->username;
}
/**
* Set password
*
* #param string $password
* #return Systemuser
*/
public function setPassword($password)
{
$this->password = $password;
return $this;
}
/**
* Get password
*
* #return string
*/
public function getPassword()
{
return $this->password;
}
/**
* Set displayname
*
* #param string $displayName
* #return Systemuser
*/
public function setDisplayname($displayname)
{
$this->displayName= $displayname;
return $this;
}
/**
* Get displayname
*
* #return string
*/
public function getDisplayname()
{
return $this->displayName;
}
/**
* Set country
*
* #param string $country
* #return Conference
*/
public function setCountry($country)
{
$this->country = $country;
return $this;
}
/**
* Get country
*
* #return string
*/
public function getCountry()
{
return $this->country;
}
/**
* Get state.
*
* #return int
*/
public function getState() {
return null;
}
/**
* Set state.
*
* #param int $state
* #return UserInterface
*/
public function setState($state) {
//does nothing
}
/**
* Set role
*
* #param \Application\Entity\Role $role
* #return Systemuser
// */
// public function setRole(\Application\Entity\Role $role = null)
// {
// $this->role = $role;
//
// return $this;
// }
/**
* Get role
*
* #return \Application\Entity\Role
*/
// public function getRole()
// {
// return $this->role;
// }
}
Role class
<?php
namespace Application\Entity;
use BjyAuthorize\Acl\HierarchicalRoleInterface;
use Doctrine\ORM\Mapping as ORM;
//use Zend\Permissions\Acl\Role\RoleInterface;
/**
* Role
*
* #ORM\Table(name="role")
* #ORM\Entity
* ORM\Entity(repositoryClass="Application\Entity\Repository\RoleRepository")
*/
class Role implements HierarchicalRoleInterface
{
/**
* #var string
*
* #ORM\Column(name="id", type="string", length=20, nullable=false)
* #ORM\Id
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=100, nullable=false)
*/
private $name;
/**
* #var Role
* #ORM\ManyToOne(targetEntity="Application\Entity\Role")
*/
protected $parent;
public function getRoleId() {
return $this->getId();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
*
* #param string $id
*/
public function setId( $id ){
$this->id = $id;
}
/**
* Set name
*
* #param string $name
* #return Role
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Get the parent role
*
* #return Role
*/
public function getParent()
{
return $this->parent;
}
/**
* Set the parent role.
*
* #param Role $parent
*
* #return void
*/
public function setParent(Role $parent)
{
$this->parent = $parent;
}
}
I finally succeeded to configure the BjyAuthorize with the following setup. However, I am still unclear on how can use 'resource_providers' and 'rule_providers' . Looks like guards are functioning well weather I define resources and rules, or I do not. I am not sure what difference those two config properties suppose to make.
bjyauthorize config file
<?php
return array(
'bjyauthorize' => array(
'identity_provider' => 'BjyAuthorize\Provider\Identity\AuthenticationIdentityProvider',
'role_providers' => array(
'BjyAuthorize\Provider\Role\ObjectRepositoryProvider' => array(
'object_manager' => 'doctrine.entitymanager.orm_default',
'role_entity_class' => 'Application\Entity\Role',
),
),
'default_role' => 'guest',
'resource_providers' => array(
'BjyAuthorize\Provider\Resource\Config' => array(
'OnlineFieldEvaluation\Controller\OnlineFieldEvaluation' => array(),
),
),
'rule_providers' => array(
'BjyAuthorize\Provider\Rule\Config' => array(
'allow' => array(
// ...
),
'deny' => array(
// ...
),
),
),
'guards' => array(
'BjyAuthorize\Guard\Controller' => array(
array(
'controller' => 'zfcuser',
'roles' => array('guest')
),
array('controller' => 'OnlineFieldEvaluation\Controller\OnlineFieldEvaluation',
'action' => array('index'),
'roles' => array('student')),
),
),
),
);
Systemuser.php
<?php
/**
* BjyAuthorize Module (https://github.com/bjyoungblood/BjyAuthorize)
*
* #link https://github.com/bjyoungblood/BjyAuthorize for the canonical source repository
* #license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Application\Entity;
use BjyAuthorize\Provider\Role\ProviderInterface;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use ZfcUser\Entity\UserInterface;
/**
* An example of how to implement a role aware user entity.
*
* #ORM\Entity
* #ORM\Table(name="systemuser")
*
* #author Tom Oram <tom#scl.co.uk>
*/
class Systemuser implements UserInterface, ProviderInterface
{
/**
* #var int
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var string
* #ORM\Column(type="string", length=255, unique=true, nullable=true)
*/
protected $username;
/**
* #var string
* #ORM\Column(type="string", unique=true, length=255)
*/
protected $email;
/**
* #var string
* #ORM\Column(type="string", length=50, nullable=true)
*/
protected $displayName;
/**
* #var string
* #ORM\Column(type="string", length=128)
*/
protected $password;
/**
* #var int
*/
protected $state;
/**
* #var \Doctrine\Common\Collections\Collection
* #ORM\ManyToMany(targetEntity="Application\Entity\Role")
* #ORM\JoinTable(name="users_roles",
* joinColumns={#ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="role_id", referencedColumnName="id")}
* )
*/
protected $roles;
/**
* Initialies the roles variable.
*/
public function __construct()
{
$this->roles = new ArrayCollection();
}
/**
* Get id.
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set id.
*
* #param int $id
*
* #return void
*/
public function setId($id)
{
$this->id = (int) $id;
}
/**
* Get username.
*
* #return string
*/
public function getUsername()
{
return $this->username;
}
/**
* Set username.
*
* #param string $username
*
* #return void
*/
public function setUsername($username)
{
$this->username = $username;
}
/**
* Get email.
*
* #return string
*/
public function getEmail()
{
return $this->email;
}
/**
* Set email.
*
* #param string $email
*
* #return void
*/
public function setEmail($email)
{
$this->email = $email;
}
/**
* Get displayName.
*
* #return string
*/
public function getDisplayName()
{
return $this->displayName;
}
/**
* Set displayName.
*
* #param string $displayName
*
* #return void
*/
public function setDisplayName($displayName)
{
$this->displayName = $displayName;
}
/**
* Get password.
*
* #return string
*/
public function getPassword()
{
return $this->password;
}
/**
* Set password.
*
* #param string $password
*
* #return void
*/
public function setPassword($password)
{
$this->password = $password;
}
/**
* Get state.
*
* #return int
*/
public function getState()
{
return $this->state;
}
/**
* Set state.
*
* #param int $state
*
* #return void
*/
public function setState($state)
{
$this->state = $state;
}
/**
* Get role.
*
* #return array
*/
public function getRoles()
{
return $this->roles->getValues();
}
/**
* Add a role to the user.
*
* #param Role $role
*
* #return void
*/
public function addRole($role)
{
$this->roles[] = $role;
}
}
Role.php
<?php
/**
* BjyAuthorize Module (https://github.com/bjyoungblood/BjyAuthorize)
*
* #link https://github.com/bjyoungblood/BjyAuthorize for the canonical source repository
* #license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Application\Entity;
use BjyAuthorize\Acl\HierarchicalRoleInterface;
use Doctrine\ORM\Mapping as ORM;
/**
* An example entity that represents a role.
*
* #ORM\Entity
* #ORM\Table(name="role")
*
* #author Tom Oram <tom#scl.co.uk>
*/
class Role implements HierarchicalRoleInterface
{
/**
* #var int
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var string
* #ORM\Column(type="string", length=255, unique=true, nullable=true)
*/
protected $roleId;
/**
* #var Role
* #ORM\ManyToOne(targetEntity="Application\Entity\Role")
*/
protected $parent;
/**
* Get the id.
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set the id.
*
* #param int $id
*
* #return void
*/
public function setId($id)
{
$this->id = (int)$id;
}
/**
* Get the role id.
*
* #return string
*/
public function getRoleId()
{
return $this->roleId;
}
/**
* Set the role id.
*
* #param string $roleId
*
* #return void
*/
public function setRoleId($roleId)
{
$this->roleId = (string) $roleId;
}
/**
* Get the parent role
*
* #return Role
*/
public function getParent()
{
return $this->parent;
}
/**
* Set the parent role.
*
* #param Role $parent
*
* #return void
*/
public function setParent(Role $parent)
{
$this->parent = $parent;
}
}

How do I reproduce this JOIN with Doctrine 2?

My join looks like this in sql:
SELECT m.*
FROM settings AS s
LEFT JOIN modules AS m on s.name = m.module
WHERE s.value = 1
AND s.category = 'module_status'
I cannot figure out how to reproduce this in Doctrine 2. Any help is greatly appreciated!
Here are my entities:
namespace Entities;
use Doctrine\Common\Collections\ArrayCollection;
/**
* Modules
*
* #Table(name="modules")
* #Entity(repositoryClass="Repositories\Modules")
*/
class Modules
{
/**
* #var integer $id
*
* #Column(name="id", type="integer", nullable=false)
* #Id
* #GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var string $module
* #Column(name="module", type="string", length=255, nullable=false)
*/
private $module;
/**
* #var string $label
* #Column(name="label", type="string", length=255, nullable=false)
*/
private $label;
/**
* #var string $package
*
* #Column(name="package", type="string", length=255, nullable=true)
*/
private $package;
/**
* #var string $path
*
* #Column(name="path", type="string", length=255, nullable=true)
*/
private $path;
/**
* #var float $version
*
* #Column(name="version", type="float", nullable=false)
*/
private $version;
public function getId() {
return $this->id;
}
public function getModule() {
return $this->module;
}
public function getLabel() {
return $this->label;
}
public function getPackage() {
return $this->package;
}
public function getPath() {
return $this->path;
}
public function getVersion() {
return $this->version;
}
public function setId($id) {
$this->id = $id;
}
public function setModule($module) {
$this->module = $module;
}
public function setLabel($label) {
$this->label = $label;
}
public function setPackage($package) {
$this->package = $package;
}
public function setPath($path) {
$this->path = $path;
}
public function setVersion($version) {
$this->version = $version;
}
}
namespace Entities;
use Doctrine\ORM\Mapping as ORM;
/**
* Settings
*
* #Table(name="settings")
* #Entity(repositoryClass="Repositories\Settings")
*/
class Settings
{
/**
* #var integer $id
*
* #Column(name="id", type="integer", nullable=false)
* #Id
* #GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var string $name
*
* #Column(name="name", type="string", length=255, nullable=true)
*/
private $name;
/**
* #var string $category
*
* #Column(name="category", type="string", length=255, nullable=true)
*/
private $category;
/**
* #var text $value
*
* #Column(name="value", type="text", nullable=true)
*/
private $value;
public function getId() {
return $this->id;
}
public function getName() {
return $this->name;
}
public function setName($name) {
$this->name = $name;
}
public function getCategory() {
return $this->category;
}
public function setCategory($category) {
$this->category = $category;
}
public function getValue() {
return $this->value;
}
public function setValue($value) {
$this->value = $value;
}
}
First, you need an association configured between the Settings and Modules entities. I'm assuming the relationship between the two is many-to-many:
Class Modules
{
/**
* #ManyToMany(targetEntity="Settings", inversedBy="modules")
* #JoinTable(name="modules_settings")
*/
private $settings;
}
Class Settings
{
/**
* #ManyToMany(targetEntity="Modules", mappedBy="settings")
*/
private $modules;
}
Then your query syntax would look like this:
$qb->select('s', 'm')
->from('Entities\Settings', 's')
->leftJoin('s.modules')
->where('s.value = 1');
I can't tell what's going on in your AND clause, but if what you have is correct, then you simply add this line to the end of your query:
->andWhere('s.category = m.status');
Thanks for the help. This is what the query ended up being:
$qb = $this->_em->createQueryBuilder()
->select('m')
->from('Entities\Modules', 'm')
->leftJoin('m.settings', 's')
->where('s.value = :enabled')
->andWhere('s.category = :moduleStatus')
->setParameter('moduleStatus', 'module_status')
->setParameter('enabled', 1)
->getQuery();
This is how I configured the modules entity:
/**
* #OneToOne(targetEntity="Entities\Settings")
* #JoinColumn(name="module", referencedColumnName="name")
*/
private $settings;

How to handle File Uploads with Doctrine in Symfony2

I am trying to upload image files with Doctrine in Symfony2 but I am getting the following error.: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'name' cannot be null.
Here is my Entity class
<?php
// src/Acme/DemoBundle/Entity/Document.php
namespace Acme\DemoBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* #ORM\Entity
* #ORM\HasLifecycleCallbacks
* #ORM\Table(name="document")
*/
class Document
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
public $id;
/**
* #ORM\Column(type="string", length=255)
* #Assert\NotBlank
*/
public $name;
/**
* #ORM\Column(type="string", length=255, nullable=true)
*/
public $path;
/**
* #Assert\File(maxSize="6000000")
*/
public $file;
public function getUploadRootDir()
{
return '/uploads';
}
/**
* Get id
*
* #return integer $id
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
*/
public function setName($name = 'akshaya')
{
$this->name = $name;
}
/**
* Get name
*
* #return string $name
*/
public function getName()
{
return $this->name;
}
/**
* Set path
*
* #param string $path
*/
public function setPath($path)
{
$this->path = $path;
}
/**
* Get path
*
* #return string $path
*/
public function getPath()
{
return $this->path;
}
/**
* #ORM\PrePersist()
*/
public function preUpload()
{
if ($this->file) {
$this->setPath($this->file->guessExtension());
}
}
/**
* #ORM\PostPersist()
*/
public function upload()
{
if (!$this->file) {
return;
}
try{
$this->file->move($this->getUploadRootDir(), $this->id.'.'.$this->file->guessExtension());
}
catch(FilePermissionException $e)
{
return false;
}
catch(\Exception $e)
{
throw new \Exception($e->getMessage());
}
unset($this->file);
}
/**
* #ORM\PreRemove()
*/
public function removeUpload()
{
if ($file = $this->getFullPath()) {
unlink($file);
}
}
public function getFullPath()
{
return null === $this->path ? null : $this->getUploadRootDir().'/'.$this->id.'.'.$this->path;
}
}
Here is the related Controller class
<?php
namespace Acme\DemoBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Acme\DemoBundle\Form\ContactForm;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Imagine\Gd\Imagine;
use Imagine\Image\Box;
use Acme\DemoBundle\Entity\Document;
class FileUploadController extends Controller
{
protected $file;
protected $document;
public function indexAction()
{
$this->document = new Document();
$form = $this->get('form.factory')
->createBuilder('form')
->add('name','text')
->add('file','file')
->getForm();
$request = $this->get('request');
if ($request->getMethod() === 'POST') {
$form->bindRequest($request);
if ($form->isValid()) {
$em = $this->get('doctrine.orm.entity_manager');
$this->document->upload();
$em->persist($this->document);
$em->flush();
$this->get('session')->setFlash('notice', 'The file is uploaded!');
}
}
return $this->render('AcmeDemoBundle:FileUpload:index.html.twig',
array("form"=>$form->createView()));
}
}
This error is not related to the upload,
The upload seems to work, but it's the insert in the database who has a problem.
The value you have provided for name is null or empty. Your database schema don't allow null value for name column.
I see 3 possible solutions:
add this annotation to the $name property: #ORM\Column(type="string", length=255, nullable="true")
provide a value for the name field, enter a value when you submit your form.
set a default name when constructing your object:
public function __construct() {
$this->name = 'foo';
}

Resources