diff --git a/src/Controller/AdminPages/BaseAdminController.php b/src/Controller/AdminPages/BaseAdminController.php index 264487d0..c15ad50b 100644 --- a/src/Controller/AdminPages/BaseAdminController.php +++ b/src/Controller/AdminPages/BaseAdminController.php @@ -32,6 +32,7 @@ namespace App\Controller\AdminPages; use App\Entity\AttachmentType; +use App\Entity\NamedDBElement; use App\Entity\StructuralDBElement; use App\Form\BaseEntityAdminForm; use App\Form\ImportType; @@ -59,7 +60,7 @@ abstract class BaseAdminController extends AbstractController } } - protected function _edit(StructuralDBElement $entity, Request $request, EntityManagerInterface $em) + protected function _edit(NamedDBElement $entity, Request $request, EntityManagerInterface $em) { $this->denyAccessUnlessGranted('read', $entity); @@ -125,7 +126,7 @@ abstract class BaseAdminController extends AbstractController ]); } - protected function _delete(Request $request, StructuralDBElement $entity, StructuralElementRecursionHelper $recursionHelper) + protected function _delete(Request $request, NamedDBElement $entity, StructuralElementRecursionHelper $recursionHelper) { $this->denyAccessUnlessGranted('delete', $entity); @@ -133,7 +134,7 @@ abstract class BaseAdminController extends AbstractController $entityManager = $this->getDoctrine()->getManager(); //Check if we need to remove recursively - if ($request->get('delete_recursive', false)) { + if ($entity instanceof StructuralDBElement && $request->get('delete_recursive', false)) { $recursionHelper->delete($entity, false); } else { $parent = $entity->getParent(); @@ -168,7 +169,7 @@ abstract class BaseAdminController extends AbstractController return $exporter->exportEntityFromRequest($entities,$request); } - protected function _exportEntity(StructuralDBElement $entity, EntityExporter $exporter, Request $request) + protected function _exportEntity(NamedDBElement $entity, EntityExporter $exporter, Request $request) { $this->denyAccessUnlessGranted('read', $entity); diff --git a/src/Controller/UserController.php b/src/Controller/UserController.php index 080491be..e8fda1be 100644 --- a/src/Controller/UserController.php +++ b/src/Controller/UserController.php @@ -29,8 +29,15 @@ namespace App\Controller; +use App\Entity\AttachmentType; +use App\Entity\Footprint; use App\Entity\User; +use App\Form\BaseEntityAdminForm; +use App\Form\UserAdminForm; use App\Form\UserSettingsType; +use App\Services\EntityExporter; +use App\Services\EntityImporter; +use App\Services\StructuralElementRecursionHelper; use Doctrine\ORM\EntityManagerInterface; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\Asset\Packages; @@ -38,16 +45,81 @@ use Symfony\Component\Form\Extension\Core\Type\PasswordType; use Symfony\Component\Form\Extension\Core\Type\RepeatedType; use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface; use Symfony\Component\Security\Core\Validator\Constraints\UserPassword; +use Symfony\Component\Serializer\SerializerInterface; use Symfony\Component\Validator\Constraints\Length; -class UserController extends AbstractController +/** + * @Route("/user") + * Class UserController + * @package App\Controller + */ +class UserController extends AdminPages\BaseAdminController { + + protected $entity_class = User::class; + protected $twig_template = 'AdminPages/UserAdmin.html.twig'; + protected $form_class = UserAdminForm::class; + protected $route_base = "user"; + + /** - * @Route("/user/info", name="user_info_self") - * @Route("/user/{id}/info") + * @Route("/{id}/edit", requirements={"id"="\d+"}, name="user_edit") + * @Route("/{id}/", requirements={"id"="\d+"}) + */ + public function edit(User $entity, Request $request, EntityManagerInterface $em) + { + return $this->_edit($entity, $request, $em); + } + + /** + * @Route("/new", name="user_new") + * @Route("/") + * + * @return \Symfony\Component\HttpFoundation\Response + */ + public function new(Request $request, EntityManagerInterface $em, EntityImporter $importer) + { + return $this->_new($request, $em, $importer); + } + + /** + * @Route("/{id}", name="user_delete", methods={"DELETE"}) + */ + public function delete(Request $request, User $entity, StructuralElementRecursionHelper $recursionHelper) + { + return $this->_delete($request, $entity, $recursionHelper); + } + + /** + * @Route("/export", name="user_export_all") + * @param Request $request + * @param SerializerInterface $serializer + * @param EntityManagerInterface $em + * @return Response + */ + public function exportAll(EntityManagerInterface $em, EntityExporter $exporter, Request $request) + { + return $this->_exportAll($em, $exporter, $request); + } + + /** + * @Route("/{id}/export", name="user_export") + * @param Request $request + * @param AttachmentType $entity + */ + public function exportEntity(User $entity, EntityExporter $exporter, Request $request) + { + return $this->_exportEntity($entity, $exporter, $request); + } + + + /** + * @Route("/info", name="user_info_self") + * @Route("/{id}/info") */ public function userInfo(?User $user, Packages $packages) { @@ -66,13 +138,13 @@ class UserController extends AbstractController } return $this->render('Users/user_info.html.twig', [ - 'user' => $user, - 'avatar' => $avatar, - ]); + 'user' => $user, + 'avatar' => $avatar, + ]); } /** - * @Route("/user/settings", name="user_settings") + * @Route("/settings", name="user_settings") */ public function userSettings(Request $request, EntityManagerInterface $em, UserPasswordEncoderInterface $passwordEncoder) { diff --git a/src/Entity/NamedDBElement.php b/src/Entity/NamedDBElement.php index d063e9f5..d6d79ca8 100644 --- a/src/Entity/NamedDBElement.php +++ b/src/Entity/NamedDBElement.php @@ -141,4 +141,9 @@ abstract class NamedDBElement extends DBElement $this->addedDate = new \DateTime('now'); } } + + public function __toString() + { + return $this->getName(); + } } diff --git a/src/Entity/User.php b/src/Entity/User.php index 3fc05990..3fd98925 100644 --- a/src/Entity/User.php +++ b/src/Entity/User.php @@ -60,7 +60,7 @@ class User extends NamedDBElement implements UserInterface, HasPermissionsInterf * @ORM\Column(type="string", length=180, unique=true) * @Assert\NotBlank */ - protected $name; + protected $name = ""; /** * //@ORM\Column(type="json"). @@ -77,7 +77,7 @@ class User extends NamedDBElement implements UserInterface, HasPermissionsInterf * @var bool True if the user needs to change password after log in * @ORM\Column(type="boolean") */ - protected $need_pw_change; + protected $need_pw_change = true; /** * @var string|null The first name of the User @@ -413,4 +413,9 @@ class User extends NamedDBElement implements UserInterface, HasPermissionsInterf return $this; } + + public function __toString() + { + return $this->getFullName(true); + } } diff --git a/src/Form/ImportType.php b/src/Form/ImportType.php index 6ed046e4..f3d06596 100644 --- a/src/Form/ImportType.php +++ b/src/Form/ImportType.php @@ -32,7 +32,9 @@ namespace App\Form; +use App\Entity\StructuralDBElement; use Symfony\Bridge\Doctrine\Form\Type\EntityType; +use Symfony\Bundle\MakerBundle\Str; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\CheckboxType; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; @@ -68,11 +70,14 @@ class ImportType extends AbstractType ['JSON' => 'json', 'XML' => 'xml','CSV'=>'csv' ,'YAML' => 'yaml'], 'label' => 'export.format', 'disabled' => $disabled]) ->add('csv_separator', TextType::class, ['data' => ';', 'label' => 'import.csv_separator', - 'disabled' => $disabled]) - ->add('parent', EntityType::class, ['class' => $data['entity_class'], 'choice_label' => 'full_path', - 'attr' => ['class' => 'selectpicker', 'data-live-search' => true], 'required' => false, - 'label' => 'parent.label', 'disabled' => $disabled]) - ->add('file', FileType::class, ['label' => 'import.file', + 'disabled' => $disabled]); + if($data['entity_class'] instanceof StructuralDBElement) { + $builder-> + add('parent', EntityType::class, ['class' => $data['entity_class'], 'choice_label' => 'full_path', + 'attr' => ['class' => 'selectpicker', 'data-live-search' => true], 'required' => false, + 'label' => 'parent.label', 'disabled' => $disabled]); + } + $builder->add('file', FileType::class, ['label' => 'import.file', 'attr' => ['class' => 'file', 'data-show-preview' => 'false', 'data-show-upload' => 'false'], 'disabled' => $disabled]) ->add('preserve_children', CheckboxType::class, ['data' => true, 'required' => false, diff --git a/src/Form/UserAdminForm.php b/src/Form/UserAdminForm.php new file mode 100644 index 00000000..9b8ab2a5 --- /dev/null +++ b/src/Form/UserAdminForm.php @@ -0,0 +1,107 @@ +security = $security; + } + + + public function buildForm(FormBuilderInterface $builder, array $options) + { + /** @var StructuralDBElement $entity */ + $entity = $options['data']; + $is_new = $entity->getID() === null; + + $builder + ->add('name', TextType::class, ['empty_data' => '', 'label' => 'user.username.label', + 'attr' => ['placeholder' => 'user.username.placeholder'], + 'disabled' => !$this->security->isGranted('edit_username', $entity), ]) + + ->add('group', EntityType::class, ['class' => Group::class, 'choice_label' => 'name', + 'attr' => ['class' => 'selectpicker', 'data-live-search' => true], 'required' => false, 'label' => 'group.label', + 'disabled' => !$this->security->isGranted('change_group', $entity), ]) + + ->add('first_name', TextType::class, ['empty_data' => '', 'label' => 'user.firstName.label', + 'attr' => ['placeholder' => 'user.firstName.placeholder'], 'required' => false, + 'disabled' => !$this->security->isGranted('edit_infos', $entity), ]) + + ->add('last_name', TextType::class, ['empty_data' => '', 'label' => 'user.lastName.label', + 'attr' => ['placeholder' => 'user.lastName.placeholder'], 'required' => false, + 'disabled' => !$this->security->isGranted('edit_infos', $entity), ]) + + ->add('email', TextType::class, ['empty_data' => '', 'label' => 'user.email.label', + 'attr' => ['placeholder' => 'user.email.placeholder'], 'required' => false, + 'disabled' => !$this->security->isGranted('edit_infos', $entity), ]) + + + ->add('department', TextType::class, ['empty_data' => '', 'label' => 'user.department.label', + 'attr' => ['placeholder' => 'user.department.placeholder'], 'required' => false, + 'disabled' => !$this->security->isGranted('edit_infos', $entity), ]) + + ; + /*->add('comment', CKEditorType::class, ['required' => false, + 'label' => 'comment.label', 'attr' => ['rows' => 4], 'help' => 'bbcode.hint', + 'disabled' => !$this->security->isGranted($is_new ? 'create' : 'edit', $entity)]); */ + + $this->additionalFormElements($builder, $options, $entity); + + //Buttons + $builder->add('save', SubmitType::class, ['label' => $is_new ? 'entity.create' : 'entity.edit.save', + 'attr' => ['class' => $is_new ? 'btn-success' : '']]) + ->add('reset', ResetType::class, ['label' => 'entity.edit.reset']); + } + + protected function additionalFormElements(FormBuilderInterface $builder, array $options, NamedDBElement $entity) + { + //Empty for Base + } +} \ No newline at end of file diff --git a/src/Services/EntityURLGenerator.php b/src/Services/EntityURLGenerator.php index ef2bbebf..515304e4 100644 --- a/src/Services/EntityURLGenerator.php +++ b/src/Services/EntityURLGenerator.php @@ -38,6 +38,7 @@ use App\Entity\NamedDBElement; use App\Entity\Part; use App\Entity\Storelocation; use App\Entity\Supplier; +use App\Entity\User; use App\Exceptions\EntityNotSupported; use Symfony\Component\HttpKernel\HttpCache\Store; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; @@ -144,6 +145,10 @@ class EntityURLGenerator return $this->urlGenerator->generate("footprint_edit", ['id' => $entity->getID()]); } + if($entity instanceof User) { + return $this->urlGenerator->generate('user_edit', ['id' => $entity->getID()]); + } + //Otherwise throw an error throw new EntityNotSupported('The given entity is not supported yet!'); } @@ -189,6 +194,10 @@ class EntityURLGenerator return $this->urlGenerator->generate('footprint_new'); } + if ($entity instanceof User) { + return $this->urlGenerator->generate('user_new'); + } + throw new EntityNotSupported('The given entity is not supported yet!'); } @@ -244,15 +253,19 @@ class EntityURLGenerator } if ($entity instanceof Manufacturer) { - return $this->urlGenerator->generate('manufacturer_new', ['id' => $entity->getID()]); + return $this->urlGenerator->generate('manufacturer_delete', ['id' => $entity->getID()]); } if ($entity instanceof Storelocation) { - return $this->urlGenerator->generate('store_location_new', ['id' => $entity->getID()]); + return $this->urlGenerator->generate('store_location_delete', ['id' => $entity->getID()]); } if ($entity instanceof Footprint) { - return $this->urlGenerator->generate('footprint_new', ['id' => $entity->getID()]); + return $this->urlGenerator->generate('footprint_delete', ['id' => $entity->getID()]); + } + + if ($entity instanceof User) { + return $this->urlGenerator->generate('user_delete', ['id' => $entity->getID()]); } throw new EntityNotSupported('The given entity is not supported yet!'); diff --git a/src/Services/TreeBuilder.php b/src/Services/TreeBuilder.php index 2797a9d7..3d7b2987 100644 --- a/src/Services/TreeBuilder.php +++ b/src/Services/TreeBuilder.php @@ -32,10 +32,12 @@ namespace App\Services; use App\Entity\DBElement; +use App\Entity\NamedDBElement; use App\Entity\StructuralDBElement; use App\Helpers\TreeViewNode; use App\Repository\StructuralDBElementRepository; use Doctrine\ORM\EntityManagerInterface; +use Symfony\Bundle\MakerBundle\Str; use Symfony\Contracts\Translation\TranslatorInterface; /** @@ -66,13 +68,15 @@ class TreeBuilder * @return TreeViewNode The Node for the given Element. * @throws \App\Exceptions\EntityNotSupported */ - public function elementToTreeNode(StructuralDBElement $element, ?string $href_type = 'list_parts', DBElement $selectedElement = null) : TreeViewNode + public function elementToTreeNode(NamedDBElement $element, ?string $href_type = 'list_parts', DBElement $selectedElement = null) : TreeViewNode { - $children = $element->getSubelements(); - $children_nodes = null; - foreach ($children as $child) { - $children_nodes[] = $this->elementToTreeNode($child, $href_type, $selectedElement); + + if ($element instanceof StructuralDBElement) { + $children = $element->getSubelements(); + foreach ($children as $child) { + $children_nodes[] = $this->elementToTreeNode($child, $href_type, $selectedElement); + } } //Check if we need to generate a href type @@ -82,7 +86,7 @@ class TreeBuilder $href = $this->url_generator->getURL($element, $href_type); } - $tree_node = new TreeViewNode($element->getName(), $href, $children_nodes); + $tree_node = new TreeViewNode($element->__toString(), $href, $children_nodes); if($children_nodes != null) { $tree_node->addTag((string) count($children_nodes)); @@ -113,7 +117,12 @@ class TreeBuilder * @var $repo StructuralDBElementRepository */ $repo = $this->em->getRepository($class_name); - $root_nodes = $repo->findRootNodes(); + + if (new $class_name() instanceof StructuralDBElement) { + $root_nodes = $repo->findRootNodes(); + } else { + $root_nodes = $repo->findAll(); + } $array = array(); @@ -134,7 +143,6 @@ class TreeBuilder $href_type = "edit"; } - foreach ($root_nodes as $node) { $array[] = $this->elementToTreeNode($node, $href_type, $selectedElement); } diff --git a/src/Twig/AppExtension.php b/src/Twig/AppExtension.php index 495af410..d385e7bb 100644 --- a/src/Twig/AppExtension.php +++ b/src/Twig/AppExtension.php @@ -39,6 +39,7 @@ use Twig\Extension\AbstractExtension; use Twig\TwigFilter; use s9e\TextFormatter\Bundles\Forum as TextFormatter; use Twig\TwigFunction; +use Twig\TwigTest; class AppExtension extends AbstractExtension { @@ -64,6 +65,15 @@ class AppExtension extends AbstractExtension ]; } + public function getTests() + { + return [ + new TwigTest('instanceof', function ($var, $instance) { + return $var instanceof $instance; + } ) + ]; + } + public function getFunctions() { return [ diff --git a/templates/AdminPages/EntityAdminBase.html.twig b/templates/AdminPages/EntityAdminBase.html.twig index 5537a622..ea71b3ae 100644 --- a/templates/AdminPages/EntityAdminBase.html.twig +++ b/templates/AdminPages/EntityAdminBase.html.twig @@ -65,7 +65,9 @@
+ {% if date(entity.addedDate) > date('1900/01/01') %} {{ entity.addedDate | localizeddate("long") }} {% else %} diff --git a/templates/AdminPages/UserAdmin.html.twig b/templates/AdminPages/UserAdmin.html.twig new file mode 100644 index 00000000..2ab2fd88 --- /dev/null +++ b/templates/AdminPages/UserAdmin.html.twig @@ -0,0 +1,15 @@ +{% extends "AdminPages/EntityAdminBase.html.twig" %} + +{% block card_title %} + {% trans %}attachment_type.caption{% endtrans %} +{% endblock %} + +{% block comment %}{% endblock %} + +{% block additional_controls %} + {{ form_row(form.group) }} + {{ form_row(form.first_name) }} + {{ form_row(form.last_name) }} + {{ form_row(form.email) }} + {{ form_row(form.department) }} +{% endblock %} \ No newline at end of file diff --git a/templates/AdminPages/_delete_form.html.twig b/templates/AdminPages/_delete_form.html.twig index 3ed3456d..6f92e951 100644 --- a/templates/AdminPages/_delete_form.html.twig +++ b/templates/AdminPages/_delete_form.html.twig @@ -7,10 +7,12 @@