I would like give permission update/delete post/category for author who created post/category
I don't know, what I must give here as second parameter. I tried:
$post=new Post();
if (Yii::$app->user->can('updatePost',['Post'=>$post]))
but gets error Getting unknown property: common\models\Post::createdBy
My Class AuthorRule:
class AuthorRule extends Rule
{
public $name = 'isAuthor';
/**
* #param string|integer $user the user ID.
* #param Item $item the role or permission that this rule is associated with
* #param array $params parameters passed to ManagerInterface::checkAccess().
* #return boolean a value indicating whether the rule permits the role or permission it is associated with.
*/
public function execute($user, $item, $params)
{
return isset($params['Post']) ? $params['Post']->CreatedBy->id == $user : false;
}
}
UPDATE:
Post Model
RBAC Controller
AuthorRule
AuthItem Table
AuthItemChild Table
Auth Assignment
You're doing the right thing, passing the object to the rule.
Are you sure your Post model actually has the createdBy property? In your other piece of code you have CreatedBy.
Most likely that typo is the problem, or your Post model does not have that field, or it's called differently (created_by?)
Oh, one more thing, if CreatedBy is a relation, and the object does not exist, trying to get its attribute (id) will produce an error. Try something like if (isset($params['Post']->CreatedBy) && $params['Post']->CreatedBy->id == $user).
Related
I am trying to define an accessor in my User model for a field which already exists. This field is called address_line_1 in my DB. However because the field name contains a number, I am unsure of how to get Laravel to recognise there is an underscore after 'line.'
Usually to define an underscore, you would camel case but in this case you can't. I have checked the Laravel documentation however this issue is not mentioned. Below is my code currently:
public function getAddressLine1Attribute($value){
return empty($value) ? '' : decrypt($value);
}
I have also tried the function name getAddress_Line_1Attribute and getAddressLine_1Attribute but this does not work.
How can I get around this?
Laravel 5.7 calls this function to check if the get mutator exists:
/**
* Determine if a get mutator exists for an attribute.
*
* #param string $key
* #return bool
*/
public function hasGetMutator($key)
{
return method_exists($this, 'get'.Str::studly($key).'Attribute');
}
'get'.Str::studly('address_line_1').'Attribute' === 'getAddressLine1Attribute'
So it seems your method name is correct.
I am working on this laravel project where user can upload an avatar image. My users table does not have any column yet to store the file location. So i was testing this in phpunit following the TDD series in laracast.
After the file is uploaded successfully and moved to the desired location in the server, i called the update method on the authenticated user like below:
$user = auth()->user();
$user->update(['avatar_location' => 'avatars/avatar.jpg']);
Note that avatar_location is not yet there on the users table. I expected this to fail but it didn't. I tried to find out what was going on so i followed through to the update() method in the model class:
//file Illuminate/Database/Eloquent/Model.php
public function update(array $attributes = [], array $options = [])
{
//dd($attributes); //prints 'avatar_location"=>"avatars/avatar.jpg'
if (! $this->exists) {
//dd($attributes);
return false;
}
return $this->fill($attributes)->save($options);
}
till this point the dd($attribute) prints the value that i passed to the update() method.
So i followed into the fill() method that is being called with the attribute parameter. However when i die dumped the received parameter from inside the fill() method i am not seeing the key=>value pair that i passed. Instead it was showing the other attributes of the user:
/**
* Fill the model with an array of attributes.
*
* #param array $attributes
* #return $this
*
* #throws \Illuminate\Database\Eloquent\MassAssignmentException
*/
public function fill(array $attributes)
{
//dd($attributes);
//does not print 'avatar_location"=>"avatars/avatar.jpg'
//rather, prints:
//array:4 [
// "name" => "Armand Mraz"
// "email" => "akautzer#example.net"
// "password" => "$2y$10$h7OG9/Toh31MsyFQc8lfg.wHeQC7maP4Bh37bea.DXU//IuRuXZi."
// "remember_token" => "X0udISwEEM"
]
$totallyGuarded = $this->totallyGuarded();
foreach ($this->fillableFromArray($attributes) as $key => $value) {
$key = $this->removeTableFromKey($key);
// The developers may choose to place some attributes in the "fillable" array
// which means only those attributes may be set through mass assignment to
// the model, and all others will just get ignored for security reasons.
if ($this->isFillable($key)) {
$this->setAttribute($key, $value);
} elseif ($totallyGuarded) {
throw new MassAssignmentException($key);
}
}
return $this;
}
I spent a lot of time trying to figure out why?
can anyone please explain?
And why the update method is not failing even though i am trying to update a column that does not exist?
Thanks,Yeasir
When you're updating an object, Laravel is trying to match the keys of the array of data and the list of fillable fields. All pairs of key/valye missing from the fillable fields are not considered. It's the reason why it's not failing.
You have to update the fillable field list (property $fillable) in your user model.
Have a look at the documentation.
If you add avatar_location in your fillable fields list and the field doesn't exist, in this case, it will throw an exception.
I search for hours to find solution for this problem but without luck.
Maybe this is duplicate post, but I didn't find it.
So, I have problem in Symfony's Service, when I call entity manager clear($entityname) method I got this error:
Warning: Illegal offset type in isset or empty.
I have no clue why this happening.
If i comment clear() method, everything works fine.
First I call ProductController
public function postProductAction(Request $request)
{
if($jsonData = $this->requestToArray($request)){
$productHandler = $this->get("admin.product_handler");
$insertNews = $productHandler->insert($jsonData);
if($insertNews === true) {
return $this->jsonResponse->setData(array(
"status" => true, "msg" => MessageConstants::SUCCESS_SEND_DATA));
}
}
$this->jsonResponse->setStatusCode(204);
return $this->jsonResponse->setData(
array("status" => false, "msg" => MessageConstants::FAILED_RECEIVE_RESPONSE));
}
Then call ProductHandler which set new product
$productRepo = new Products();
$productRepo->setCarmodels(json_encode($data['ModelId']));
$productRepo->setCategoryid($category);
$productRepo->setDescription($data['Description']);
$productRepo->setDiscount($data['Discount']);
$productRepo->setDiscountprice($data['DiscountPrice']);
$this->em->persist($productRepo);
$this->em->flush($productRepo);
$insertOther = $this->update($productRepo->getId(), $data);
$this->em->clear($productRepo);
insertAnotfer call update,because there is some action which require to get product id, so I need first to insert then do update.
$product = $productRepo->find((int)$id);
$product->setCarmodels(json_encode($data['ModelId']));
$product->setCategoryid($category);
$product->setDescription($data['Description']);
$product->setDiscount($data['Discount']);
$product->setDiscountprice($data['DiscountPrice']);
In update I also call clear method
$this->em->flush($product);
$this->em->clear($product);
And then I get this error. I tried to remove clear method from update but no luck. Error will not be trigger only if I set clear() method without entity in insert function.
The EntityManager::clear method takes the name of an entity type, not an actual instance of an entity:
\Doctrine\ORM\EntityManager:
/**
* Clears the EntityManager. All entities that are currently managed
* by this EntityManager become detached.
*
* #param string|null $entityName if given, only entities of this type will get detached
*
* #return void
*/
public function clear($entityName = null)
{
$this->unitOfWork->clear($entityName);
}
It seems like what you need is detach - the correct method for disassociating an entity instance from the entity manager:
http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/working-with-objects.html#detaching-entities
\Doctrine\ORM\EntityManager:
/**
* Detaches an entity from the EntityManager, causing a managed entity to
* become detached. Unflushed changes made to the entity if any
* (including removal of the entity), will not be synchronized to the database.
* Entities which previously referenced the detached entity will continue to
* reference it.
*
* #param object $entity The entity to detach.
*
* #return void
*
* #throws ORMInvalidArgumentException
*/
public function detach($entity)
{
if ( ! is_object($entity)) {
throw ORMInvalidArgumentException::invalidObject('EntityManager#detach()' , $entity);
}
$this->unitOfWork->detach($entity);
}
I don't believe you should have the parameter specified within either the flush or clear functions.
Have you tried like this (without entity as parameter):
$this->em->flush();
$this->em->clear();
I'm not certain if that will work for you, but can you try it and see if that helps? I could be wrong about this though, so if someone has a better suggestion, please post.
Using Symfony2/Doctrine ORM
I have an entity "ProductCategory".
ProductCategory ( fields )
id (int)
displayName (string)
I'm wanting to create a route with param converters. This is what I have. According to the documentation here it should work.
/**
* #Route("/products/{category_name}")
* #ParamConverter("c", class="AppBundle:ProductCategory", options={"mapping": { "displayName" = "category_name"}})
*/
public function viewProductPageAction(ProductCategory $c)
{
return $this->render('templates/view-product.html.twig');
}
So what's going on up there? I want to convert the route key "category_name" to a ProductCategory entity by it's field DisplayName and assign it to $c.
Seems easy enough. Assign the category_name to the displayName field in the mapping option. But I'm getting this error.
Unable to guess how to get a Doctrine instance from the request information. 500 - Logic exception
What is the reason I'm getting the error, and how am I misinterpreting the documentation? Thanks in advance.
Well you were close enough. Arguments passed to mapping are in reversed order. The right syntax you're looking for here is like this:
/**
* #Route("/products/{category_name}")
* #ParamConverter("c", class="AppBundle:ProductCategory", options={"mapping": { "category_name" = "displayName"}})
*/
I have two classes with a bidirectional relationship: Player and Team Each player must have exactly one team and each team can have many players.
When I use the default form field (select) and I submit 0 (by manually editing the HTML) the form error shows correctly. However if I use a custom form field type and submit 0 there's no form error but an exception:
Catchable Fatal Error: Argument 1 passed to
...\Entity\Player::setTeam() must be an instance of ...\Entity\Team,
null given, called in
...\vendor\symfony\symfony\src\Symfony\Component\PropertyAccess\PropertyAccessor.php
on line 360 and defined in ...\Entity\Player.php line 58
How do I show a normal form error instead of this exception?
My classes are straighforward (only the relevant parts posted):
Team.php
class Team {
/**
* #ORM\OneToMany(targetEntity="...\Entity\Player", mappedBy="team")
*/
protected $players;
}
Player.php
class Player {
/**
* #var Team
*
* #ORM\ManyToOne(targetEntity="...\Entity\Team", inversedBy="players")
* #ORM\JoinColumn(name="team_id", referencedColumnName="id", nullable=false)
* #Assert\Valid
*/
protected $team;
/**
* Set team
*
* #param Team $team
* #return Player
*/
public function setTeam(Team $team) {
$this->team = $team;
return $this;
}
/**
* Get team
*
* #return Team
*/
public function getTeam() {
return $this->team;
}
}
The reverseTransform function of my DataTransformer looks like this:
public function reverseTransform($value)
{
if(!$value)
{
return $this->multiple ? array() : 0;
}
//... get entity
}
If you have created a custom form field with a custom data transformer, it is your responsibility to validate client datas. To get the generic message (This value is not valid), you need to throw a TransformationFailedException in your data transformer. Then, everything will be handled by the form component.
EDIT: By default majority of the data transformers in the Symfony core, converts a blank value to null. The responsibility of the data transformer is to convert client data to model data and eventually to detect major error like non-acceptable value for a choice list or missing data in case of datetime field, etc. It is not to validate the data which is the resposibility of the validator component. Then, it lets the validator component make the final validation which is often more complex than a simple data transformer. IMHO, you're currently mixing data transfomer and validation concern.
EDIT: Additionally, you need to allow in your domain object what the data transformer return itself (here, the null value).