using of unique constraint making the user unable to login in symfony2 - symfony

I have used an unique constraint for the username in the registration form of the user.
User entity has following code
/*
* #UniqueEntity(fields="username",message="Username is already in use")
*/
class users
{
/**
* #var string
* #Assert\NotBlank(message="username should not be blank")
* #ORM\Column(name="username", type="string", length=40)
*
*/
private $username;
/**
* #var string
* #Assert\NotBlank(message="password should not be blank")
* #ORM\Column(name="password", type="string", length=40)
*/
private $password;
}
For registration every thing went fine with this entity when comes to login it is showing error username already in use. Can we keep the unique constraint within controller i.e within form.so that only for registration form uniqueness is applied.

Use validation groups:
http://symfony.com/doc/2.1/book/validation.html#validation-groups
(when you follow the link - you'll see very similar case: user and registration)
edit:
I assume that you have an "user_type" field in your user entity (for example possible values could be: "normal_user" and "affiliate"). If so, then you just need specify these two fields combination as a unique. Like this:
#UniqueEntity(fields={"username", "user_type"},message="Username is already in use") */

Related

Strange Issue With Entity Relationship in Symfony 4

This is a very odd one, i'll try to explain with couple of sample entities.
class Property{
/**
* #var string
* #ORM\Column(type="string", length=10)
*/
private $postCode;
/**
* #var InstructionToSell
* #ORM\OneToOne(targetEntity="App\Entity\InstructionToSell")
* #ORM\JoinColumn(nullable=true)
*/
private $instructionToSell;
}
class InstructionToSell{
/**
* #var Property
* #ORM\OneToOne(targetEntity="App\Entity\Property")
* #ORM\JoinColumn(nullable=true)
*/
private $property;
}
So two sample entities, the property can have an instruction to sell entity and vice versa. I then have a very basic post code search method in the repo:
/**
* #param string $postCode
* #return array|null
*/
public function searchByPostcode(string $postCode) : ?array{
$builder = $this->createQueryBuilder('p');
$builder->where(
$builder->expr()->like('p.postCode',':postCode')
)->setParameter('postCode',str_replace(' ','','%'.$postCode.'%'));
return $builder->getQuery()->getResult();
}
It all works fine except for one very strange thing. If say a property had the Uk post code of "YO12 7YA" and we run a search for "YO127YA" then it's bringing back a result, but if we use "YO12 7YA" it's bringing back a result but the instructionToSell is null on the property, but it's not null if i remove the space from the search term.
I'm aware this search isn't the best as it stands, need to strip spaces out of the column as well, but the point i am making is, the same code runs for "YO12 7YA" and "YO127YA" which brings back the same property, but one of them has the relationship matched to the instruction to sell, the other it's null.
Why would this happen? It's exactly the same property it's bringing back.

Symfony2 Doctrine trying to insert record twice? Race condition?

We have a survey building application built in Symfony2 (think Survey Monkey or Google Forms). When a member of public accesses the survey, the various questions are built dynamically using Symfony's Form Builder and their answers are persisted using Doctrine. We currently collect an average of 1000 completed surveys a day without any trouble, but, every now and again, we get an Doctrine\DBAL exception.
Each answer to a question is persisted in a table which has a unique key consisting of the ID of the person filling in the survey and the ID of the question they are answering. Sometimes, when Doctrine tries to INSERT their answer, this key is violated and the query fails. As I mentioned, this happens fairly infrequently and we have been unable to replicate it on our test environment.
Things are made more complicated by the fact that all the Symfony Forms are build dynamically. Here is the code that actually does the persisting of the form data
public function save(\Symfony\Component\Form\Form $form, \Our\Namspace\Entity\Participant $participant)
{
/**
* $surveyReponse
*
* #var \Our\Namespace\Entity\SurveyResponse
*/
foreach ($form->getData() as $surveyResponseKey => $surveyResponse) {
$subQuestionId = $this->getQuestionIdFromSurveyResponseKey($surveyResponseKey);
$subQuestion = $this->getSubQuestionSettingsBySubQuestionId($subQuestionId);
if ($surveyResponse) {
$surveyResponse->setParticipant($participant)->setSubQuestion($subQuestion);
$participant->addResponse($surveyResponse);
$this->em->persist($surveyResponse);
}
$this->em->flush();
}
return true;
}
You can see that we encode the ID of the question (which is known as a SubQuestion in our domain) in the Form data in order to get the (sub)Question entity, then we set the Participant and the SubQuestion on the SurveyResponse object before persisting it. $this->em is just the Doctrine Entity Manager.
Without seeing all the code, it is probably difficult for anyone to figure out what is happening, but if anyone has had a similar problem in the past, maybe they could offer some advice.
We can and should wrap the persist and flush operations in a try/catch block and then handle the exception, but we'd really like to know why it is happening!
The relevant bits of the SurveyResponse entity look like
class SurveyResponse implements SurveyAwareInterface
{
/**
* id of the response.
*
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $id;
/**
* the subQuestion to which the response refers.
*
* #var SurveySubQuestion
*
* #ORM\ManyToOne(targetEntity="\Our\Namspace\Entity\SurveySubQuestion", inversedBy="surveyResponses")
* #ORM\JoinColumn(name="sub_question_id", referencedColumnName="id")
*/
protected $subQuestion;
/**
* the participant.
*
* #var AbstractParticipant
*
* #ORM\ManyToOne(targetEntity="Our\Namespace\Entity\Participant", inversedBy="responses")
* #ORM\JoinColumn(name="participant_id", referencedColumnName="id", onDelete="CASCADE")
*/
protected $participant;
And there is this annotation in the Entity;
* #ORM\Table(name="survey_response",
* uniqueConstraints= #ORM\UniqueConstraint(
* name="participant_response", columns={"participant_id", "sub_question_id"})})
*

SonataAdminBundle: set permission depending on field value

I have a working SonataAdmin+FOSUser (WITHOUT SonataUserBundle) setup with roles and ACL enabled. This is working fine, every user has access to different admins depending on their roles.
Now I need to go a bit deeper. I would like to restrict access to one of the admin depending on the value of an association of the underlying entity.
Lets say I have this:
/**
* #ORM\Entity
*/
class Content
{
/**
* #var string
*
* #ORM\ManyToOne(targetEntity="ContentType", inversedBy="contents")
*/
private $type;
}
/**
* #ORM\Entity
*/
class ContentType
{
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255)
*/
private $name;
}
I would like the following:
Users with ROLE_XXXXX : have access to all contents with content type name 'XXXXX'
Users with ROLE_YYYYY : have access to all contents with content type name 'YYYYY'
...
Of course it also means that when creating a new content or filtering the list of contents, users should not be able to select a content type on which they don't have any permission.
I have tried this with no luck:
php app/console acl:set --role=ROLE_XXXXX MASTER MyBundle/ContentType:2

How to define multiple many-to-one relations between two Doctrine tables?

I've got a problem with doctrine with Symfony when I try to define to relations Many-to-one between the table Challenge and User getting the next error.
Error when I try to define:
The table User has the attribute: id, challengesMaked, challengesReceived and the table Challenge has these atributes: id, idUser1, idUser2 where idUser1 I want to relation with id from User and idUser2 I want to relation with id from User too. The relation between User and Challenge are One to Many (One user can challenge to another user) and between Challenge to User are Many to One (One challenge is received only by a User)
So, how can I define this attributes in my entity to fix my bug. Right now, in my User Entity I have defined these attributes like ...
/**
* #var Challenge ArrayCollection
* #ORM\OneToMany(targetEntity="\MQL\PlayerBundle\Entity\Challenge", mappedBy="idUser1", cascade={"persist"})
*/
protected $challengesMaked;
/**
* #var Challenge ArrayCollection
* #ORM\OneToMany(targetEntity="\MQL\PlayerBundle\Entity\Challenge", mappedBy="idUser2", cascade={"persist"})
*/
protected $challengesReceived;
And in the Challenge Entity I have defined ...
/**
* #var User ArrayCollection
* #ORM\ManyToOne(targetEntity="\FOS\UserBundle\Entity\User", inversedBy="challengesMaked")
**/
protected $idUser1; //Challenger
/**
* #var User ArrayCollection
* #ORM\ManyToOne(targetEntity="\FOS\UserBundle\Entity\User", inversedBy="challengesReceived")
**/
protected $idUser2; //Challenged
What am I doing wrong?

Doctrine: authorize NULL in a foreign composite key

I have the following entity:
/**
* SeriesAuthorRole
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="Blog\Bundle\CoreBundle\Entity\SeriesAuthorRoleRepository")
*/
class SeriesAuthorRole extends AuthorRoleAbstract
{
/**
* #var Series
*
* #ORM\ManyToOne(targetEntity="Blog\Bundle\CoreBundle\Entity\Series", inversedBy="authors")
* #ORM\JoinColumn(name="series", referencedColumnName="id", nullable=false)
* #ORM\Id
*/
private $series;
/**
* #var Author
*
* #ORM\ManyToOne(targetEntity="Blog\Bundle\CoreBundle\Entity\Author")
* #ORM\JoinColumn(name="author", referencedColumnName="id", nullable=false)
* #ORM\Id
*/
protected $author;
/**
* #var Role
*
* #todo Must be nullable
*
* #ORM\ManyToOne(targetEntity="Blog\Bundle\CoreBundle\Entity\Role")
* #ORM\JoinColumn(name="role", referencedColumnName="id", nullable=true)
* #ORM\Id
*/
protected $role;
// ... Getters, setters
}
The idea behind it is quite simple: We have author, role and series entities. A series can have several authors with various roles. A same author can fulfill multiple roles in a series.
Sometimes, we don't know exactly what was the role of the author. In this case, the NULL value will be used for the role, the NULL value standing for "I don't know".
I was taught not to use NULL in foreign composite keys unless it has meaning. Well, it has meaning here, and I know that this could be implemented without Doctrine. However, for now, Symfony 2 throws that error:
Entity of type Blog\Bundle\CoreBundle\Entity\BandAuthorRole is missing an assigned ID for field 'role'. The identifier generation strategy for this entity requires the ID field to be populated before EntityManager#persist() is called. If you want automatically generated identifiers instead you need to adjust the metadata mapping accordingly.
500 Internal Server Error - ORMException
So how can I authorize NULL values in foreign composite keys ? Is it possible at all with Doctrine ?
Your #JoinColumn annotation is correct with referencing to http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/annotations-reference.html#annref-joincolumn
However,
Every entity with a composite key cannot use an id generator other
than “ASSIGNED”. That means the ID fields have to have their values
set before you call EntityManager#persist($entity).
http://docs.doctrine-project.org/en/2.0.x/tutorials/composite-primary-keys.html#general-considerations

Resources