SonataAdminBundle: set permission depending on field value - symfony

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

Related

Sonata admin – blank page on production when ModelManagerException is thrown

I have defined unique constraint on one property of my entity.
/**
* #var string
* #ORM\Column(type="string", length=10, unique=true)
*/
protected $customID;
In Sonata admin, when new object is created with same ID, blank page on production is shown (in dev production, I can see that ModelManagerException is thrown, which is expected result).
How can I display an error on production?
Maybe use https://symfony.com/doc/current/reference/constraints/UniqueEntity.html for that field and it will show validation error before saving so no exception will be thrown.
Example:
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
/**
* #ORM\Entity
* #UniqueEntity("customID")
*/
class YourEntity {}

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?

createFormBuilder entity type dont set curent value

i setup form createFormBuilder
$form = $this->createFormBuilder($ob)
->add('mkeywordsId', 'entity',['label'=>'rodzaj','class' => 'Miejsce\ObiektyBundle\Entity\Mkeywords'])
and this select dont have curent option selected, how to do this?
when i put ->add('mkeywordsId', 'text') i see text witch 1445 value , and this key exists in Mkeywords select list so why is not selected ?
I have only mapping from Mmiejsce, mkeywords dont have mappings because is not only one entity use keywords. In this situation Mmiejsce have connection one Mmiejsce to one Mkeyword.
Maybe i can map in createFormBuilder->add ?
Mmiejsce.mkeywordsId = Mkeywords.id and want get Mkeywords.name
class Mmiejsce
/**
* Rodzaj
* #ORM\ManyToOne(targetEntity="Mkeywords")
* #ORM\JoinColumn(name="keyword_id", referencedColumnName="id")
* #var integer
*/
private $mkeywordsId;
}
class Mkeywords
{
/**
* #var string
*/
private $name;
/**
* #var integer
*/
private $mkeywordsId;
Sounds like the relationships between your entities are not mapped correctly. Can you post the contents/schema of the entity class for this form?

Access control lists in Symfony2 using FOSUserBundle - adding roles to a user

I'm hoping this is more simple than the docs I've been reading.
I have a number of entities with ManyToOne relationships with a standard FOSUserbundle user entity that can login users, register them, logout etc.
class User extends BaseUser
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
public function __construct()
{
parent::__construct();
}
Each of my users can also have a number of pets. I.e. here's the cat entity (simplified):
class Cat
{
/**
* #var integer
*
* #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;
/**
* #ORM\ManyToOne(targetEntity="User")
* #ORM\JoinColumn(name="user_id", referencedColumnName="id")
**/
private $user_id;
How should I add an access control list user role that defines if the user has any cats or not, and if they do, allows them onto the "cats only" part of my website.
Note (slightly related): I feel mildly retarded when it comes to database design using doctrine, I'll upvote anyone that can point me to a good tutorial / explanation of designing things with different kind of joins, especially if it's a in Symfony/Doctrine environment.
Well, since you haven't gotten anything else yet. I'll throw something out there but my experience is only moderate so far.
In the controller for your cats owners page, you could query if the user has any associated cat entities.
You need to add OneToMany/ManyToOne annotations to your user and cat class, and a variable for the associations. This you could review straight out of the doctrine section of the symfony2 book (If you are working with Symfony2 and haven't taken the time to read the book, that is the minimal level of knowledge to work with the full stack and I suggest you read it all). (Do you really need a entity class just for cat, you could have a pet entity with a "type" option.)
check the security context to ensure logged in, then query db.
$em = $this->getDoctrine()->getManager();
$ownersCats = $em->getRepository('PetsPetSiteBundle:Blog')->findBy(array('type'=>'cat'));
or for one result only
$ownersCats = $em->getRepository('PetsPetSiteBundle:Blog')->findOneBy(array('type'=>'cat'));
Once you have this result if it comes back false, you know he has no cats. Otherwise continue.
Obviously you could make this perform better by only querying for id's or something if you don't plan on using the entities on that page or just performing a count query and seeing if it's greater than 0?

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

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") */

Resources