diff --git a/src/Form/PartType.php b/src/Form/PartType.php index 81c519ad..49ab4e9f 100644 --- a/src/Form/PartType.php +++ b/src/Form/PartType.php @@ -47,30 +47,50 @@ use Symfony\Component\Form\Extension\Core\Type\ResetType; use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\OptionsResolver\OptionsResolver; +use Symfony\Component\Security\Core\Security; class PartType extends AbstractType { + protected $security; + + public function __construct(Security $security) + { + $this->security = $security; + } + + public function buildForm(FormBuilderInterface $builder, array $options) { + $part = $options['data']; + $builder ->add('name', TextType::class, ['empty_data'=>'', 'label'=> 'name.label', - 'attr' => ['placeholder' => 'part.name.placeholder']]) + 'attr' => ['placeholder' => 'part.name.placeholder'], + 'disabled' => !$this->security->isGranted('name.edit', $part)]) ->add('description', TextType::class, ['required'=>false, 'empty_data'=>'', - 'label'=> 'description.label', 'help' => 'bbcode.hint', 'attr' => ['placeholder' => 'part.description.placeholder']]) + 'label'=> 'description.label', 'help' => 'bbcode.hint', 'attr' => ['placeholder' => 'part.description.placeholder'], + 'disabled' => !$this->security->isGranted('description.edit', $part)]) ->add('instock', IntegerType::class, - ['attr' => ['min'=>0, 'placeholder' => 'part.instock.placeholder'], 'label'=> 'instock.label']) + ['attr' => ['min'=>0, 'placeholder' => 'part.instock.placeholder'], 'label'=> 'instock.label', + 'disabled' => !$this->security->isGranted('instock.edit', $part)]) ->add('mininstock', IntegerType::class, - ['attr' => ['min'=>0, 'placeholder' => 'part.mininstock.placeholder'], 'label'=> 'mininstock.label']) + ['attr' => ['min'=>0, 'placeholder' => 'part.mininstock.placeholder'], 'label'=> 'mininstock.label', + 'disabled' => !$this->security->isGranted('mininstock.edit', $part)]) ->add('category', EntityType::class, ['class' => Category::class, 'choice_label' => 'full_path', - 'attr' => ['class' => 'selectpicker', 'data-live-search' => true], 'label'=> 'category.label']) + 'attr' => ['class' => 'selectpicker', 'data-live-search' => true], 'label'=> 'category.label', + 'disabled' => !$this->security->isGranted('move', $part)]) ->add('storelocation', EntityType::class, ['class' => Storelocation::class, 'choice_label' => 'full_path', - 'attr' => ['class' => 'selectpicker', 'data-live-search' => true], 'required' => false, 'label'=> 'storelocation.label']) + 'attr' => ['class' => 'selectpicker', 'data-live-search' => true], 'required' => false, 'label'=> 'storelocation.label', + 'disabled' => !$this->security->isGranted('storelocation.edit', $part)]) ->add('manufacturer', EntityType::class, ['class' => Manufacturer::class, 'choice_label' => 'full_path', - 'attr' => ['class' => 'selectpicker', 'data-live-search' => true], 'required' => false, 'label'=> 'manufacturer.label']) + 'attr' => ['class' => 'selectpicker', 'data-live-search' => true], 'required' => false, 'label'=> 'manufacturer.label', + 'disabled' => !$this->security->isGranted('manufacturer.edit', $part)]) ->add('manufacturer_product_url', UrlType::class, ['required'=>false, 'empty_data' => '', - 'label'=> 'manufacturer_url.label']) + 'label'=> 'manufacturer_url.label', + 'disabled' => !$this->security->isGranted('manufacturer.edit', $part)]) ->add('comment', CKEditorType::class, ['required'=>false, - 'label'=> 'comment.label', 'attr' => ['rows'=> 4], 'help' => 'bbcode.hint']) + 'label'=> 'comment.label', 'attr' => ['rows'=> 4], 'help' => 'bbcode.hint', + 'disabled' => !$this->security->isGranted('comment.edit', $part)]) //Buttons ->add('save', SubmitType::class, ['label' => 'part.edit.save']) diff --git a/src/Security/Voter/PartVoter.php b/src/Security/Voter/PartVoter.php index f0fad559..93732b4f 100644 --- a/src/Security/Voter/PartVoter.php +++ b/src/Security/Voter/PartVoter.php @@ -31,7 +31,15 @@ class PartVoter extends ExtendedVoter if ($subject instanceof Part) { - return in_array($attribute, $this->resolver->listOperationsForPermission('parts'), false); + + //Check if a sub permission should be checked -> $attribute has format name.edit + if(strpos($attribute, '.') !== false) { + [$perm, $op] = explode('.', $attribute); + return in_array($op, $this->resolver->listOperationsForPermission('parts_'.$perm), false); + } + + + return in_array($attribute, $this->resolver->listOperationsForPermission('parts'), false); } return false; @@ -41,6 +49,13 @@ class PartVoter extends ExtendedVoter protected function voteOnUser($attribute, $subject, User $user): bool { if($subject instanceof Part) { + + //Check for sub permissions + if(strpos($attribute, '.') !== false) { + [$perm, $op] = explode('.', $attribute); + return $this->resolver->inherit($user, 'parts_'. $perm, $op) ?? false; + } + //Null concealing operator means, that no return $this->resolver->inherit($user, 'parts', $attribute) ?? false; } diff --git a/templates/show_part_info.html.twig b/templates/show_part_info.html.twig index ed6df593..af7928f2 100644 --- a/templates/show_part_info.html.twig +++ b/templates/show_part_info.html.twig @@ -23,7 +23,12 @@
{{ part.manufacturer.name ?? ""}}
-

{{ part.name }}

+

{{ part.name }} + {# You need edit permission to use the edit button #} + {% if is_granted('edit', part) %} + + {% endif %} +

{{ part.description|bbCode }}
@@ -63,13 +68,13 @@