diff --git a/config/packages/security.yaml b/config/packages/security.yaml index 5478adc3..ab03ff47 100644 --- a/config/packages/security.yaml +++ b/config/packages/security.yaml @@ -1,6 +1,6 @@ security: encoders: - App\Entity\User: + App\Entity\UserSystem\User: algorithm: auto # https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers @@ -8,7 +8,7 @@ security: # used to reload user from session & other features (e.g. switch_user) app_user_provider: entity: - class: App\Entity\User + class: App\Entity\UserSystem\User property: name firewalls: dev: diff --git a/src/Controller/AdminPages/AttachmentTypeController.php b/src/Controller/AdminPages/AttachmentTypeController.php index 54d9bec1..d9585a2d 100644 --- a/src/Controller/AdminPages/AttachmentTypeController.php +++ b/src/Controller/AdminPages/AttachmentTypeController.php @@ -33,7 +33,7 @@ namespace App\Controller\AdminPages; use App\Entity\Attachments\AttachmentType; -use App\Form\BaseEntityAdminForm; +use App\Form\AdminPages\BaseEntityAdminForm; use App\Services\EntityExporter; use App\Services\EntityImporter; use App\Services\StructuralElementRecursionHelper; diff --git a/src/Controller/AdminPages/BaseAdminController.php b/src/Controller/AdminPages/BaseAdminController.php index f8051d57..fe04cda0 100644 --- a/src/Controller/AdminPages/BaseAdminController.php +++ b/src/Controller/AdminPages/BaseAdminController.php @@ -33,8 +33,9 @@ namespace App\Controller\AdminPages; use App\Entity\Base\NamedDBElement; use App\Entity\Base\StructuralDBElement; -use App\Form\BaseEntityAdminForm; -use App\Form\ImportType; +use App\Form\AdminPages\BaseEntityAdminForm; +use App\Form\AdminPages\ImportType; +use App\Form\AdminPages\MassCreationForm; use App\Services\EntityExporter; use App\Services\EntityImporter; use App\Services\StructuralElementRecursionHelper; @@ -118,10 +119,30 @@ abstract class BaseAdminController extends AbstractController } } + //Mass creation form + $mass_creation_form = $this->createForm(MassCreationForm::class, ['entity_class' => $this->entity_class]); + $mass_creation_form->handleRequest($request); + + if ($mass_creation_form->isSubmitted() && $mass_creation_form->isValid()) { + $data = $mass_creation_form->getData(); + + dump($data); + + //Create entries based on input + $errors = $importer->massCreation($data['lines'], $this->entity_class, $data['parent']); + + //Show errors to user: + foreach ($errors as $name => $error) { + /** @var $error ConstraintViolationList */ + $this->addFlash('error', $name . ":" . $error); + } + } + return $this->render($this->twig_template, [ 'entity' => $new_entity, 'form' => $form->createView(), - 'import_form' => $import_form->createView() + 'import_form' => $import_form->createView(), + 'mass_creation_form' => $mass_creation_form->createView() ]); } diff --git a/src/Controller/AdminPages/CategoryController.php b/src/Controller/AdminPages/CategoryController.php index dcb08e93..11098663 100644 --- a/src/Controller/AdminPages/CategoryController.php +++ b/src/Controller/AdminPages/CategoryController.php @@ -34,8 +34,8 @@ namespace App\Controller\AdminPages; use App\Entity\Attachments\AttachmentType; use App\Entity\Parts\Category; -use App\Form\BaseEntityAdminForm; -use App\Form\CategoryAdminForm; +use App\Form\AdminPages\BaseEntityAdminForm; +use App\Form\AdminPages\CategoryAdminForm; use App\Services\EntityExporter; use App\Services\EntityImporter; use App\Services\StructuralElementRecursionHelper; diff --git a/src/Controller/AdminPages/DeviceController.php b/src/Controller/AdminPages/DeviceController.php index 963d0862..06d15fd2 100644 --- a/src/Controller/AdminPages/DeviceController.php +++ b/src/Controller/AdminPages/DeviceController.php @@ -35,7 +35,7 @@ namespace App\Controller\AdminPages; use App\Entity\Attachments\AttachmentType; use App\Entity\Devices\Device; -use App\Form\BaseEntityAdminForm; +use App\Form\AdminPages\BaseEntityAdminForm; use App\Services\EntityExporter; use App\Services\EntityImporter; use App\Services\StructuralElementRecursionHelper; diff --git a/src/Controller/AdminPages/FootprintController.php b/src/Controller/AdminPages/FootprintController.php index 28c764d0..666980c2 100644 --- a/src/Controller/AdminPages/FootprintController.php +++ b/src/Controller/AdminPages/FootprintController.php @@ -35,7 +35,7 @@ namespace App\Controller\AdminPages; use App\Entity\Attachments\AttachmentType; use App\Entity\Parts\Footprint; -use App\Form\BaseEntityAdminForm; +use App\Form\AdminPages\BaseEntityAdminForm; use App\Services\EntityExporter; use App\Services\EntityImporter; use App\Services\StructuralElementRecursionHelper; diff --git a/src/Controller/AdminPages/ManufacturerController.php b/src/Controller/AdminPages/ManufacturerController.php index e2520161..6e4f4aba 100644 --- a/src/Controller/AdminPages/ManufacturerController.php +++ b/src/Controller/AdminPages/ManufacturerController.php @@ -36,8 +36,8 @@ use App\Entity\Attachments\AttachmentType; use App\Entity\Parts\Manufacturer; use App\Entity\Parts\Supplier; -use App\Form\BaseEntityAdminForm; -use App\Form\CompanyForm; +use App\Form\AdminPages\BaseEntityAdminForm; +use App\Form\AdminPages\CompanyForm; use App\Services\EntityExporter; use App\Services\EntityImporter; use App\Services\StructuralElementRecursionHelper; diff --git a/src/Controller/AdminPages/StorelocationController.php b/src/Controller/AdminPages/StorelocationController.php index d5f1ab4b..5e28b001 100644 --- a/src/Controller/AdminPages/StorelocationController.php +++ b/src/Controller/AdminPages/StorelocationController.php @@ -34,8 +34,8 @@ namespace App\Controller\AdminPages; use App\Entity\Attachments\AttachmentType; use App\Entity\Parts\Storelocation; -use App\Form\BaseEntityAdminForm; -use App\Form\StorelocationAdminForm; +use App\Form\AdminPages\BaseEntityAdminForm; +use App\Form\AdminPages\StorelocationAdminForm; use App\Services\EntityExporter; use App\Services\EntityImporter; use App\Services\StructuralElementRecursionHelper; diff --git a/src/Controller/AdminPages/SupplierController.php b/src/Controller/AdminPages/SupplierController.php index d3da9c5d..31be2776 100644 --- a/src/Controller/AdminPages/SupplierController.php +++ b/src/Controller/AdminPages/SupplierController.php @@ -35,8 +35,8 @@ namespace App\Controller\AdminPages; use App\Entity\Attachments\AttachmentType; use App\Entity\Parts\Supplier; -use App\Form\BaseEntityAdminForm; -use App\Form\CompanyForm; +use App\Form\AdminPages\BaseEntityAdminForm; +use App\Form\AdminPages\CompanyForm; use App\Services\EntityExporter; use App\Services\EntityImporter; use App\Services\StructuralElementRecursionHelper; diff --git a/src/Controller/UserController.php b/src/Controller/UserController.php index 2a728a19..b0ed066a 100644 --- a/src/Controller/UserController.php +++ b/src/Controller/UserController.php @@ -32,7 +32,7 @@ namespace App\Controller; use App\Entity\Attachments\AttachmentType; use App\Entity\Parts\Footprint; use App\Entity\UserSystem\User; -use App\Form\BaseEntityAdminForm; +use App\Form\AdminPages\BaseEntityAdminForm; use App\Form\UserAdminForm; use App\Form\UserSettingsType; use App\Services\EntityExporter; diff --git a/src/Form/BaseEntityAdminForm.php b/src/Form/AdminPages/BaseEntityAdminForm.php similarity index 99% rename from src/Form/BaseEntityAdminForm.php rename to src/Form/AdminPages/BaseEntityAdminForm.php index e7dc268a..e9df8e96 100644 --- a/src/Form/BaseEntityAdminForm.php +++ b/src/Form/AdminPages/BaseEntityAdminForm.php @@ -29,7 +29,7 @@ * */ -namespace App\Form; +namespace App\Form\AdminPages; use App\Entity\Base\NamedDBElement; diff --git a/src/Form/CategoryAdminForm.php b/src/Form/AdminPages/CategoryAdminForm.php similarity index 98% rename from src/Form/CategoryAdminForm.php rename to src/Form/AdminPages/CategoryAdminForm.php index eaf658ab..b88be820 100644 --- a/src/Form/CategoryAdminForm.php +++ b/src/Form/AdminPages/CategoryAdminForm.php @@ -29,10 +29,11 @@ * */ -namespace App\Form; +namespace App\Form\AdminPages; use App\Entity\Base\NamedDBElement; +use App\Form\AdminPages\BaseEntityAdminForm; use Symfony\Component\Form\Extension\Core\Type\CheckboxType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\FormBuilderInterface; diff --git a/src/Form/CompanyForm.php b/src/Form/AdminPages/CompanyForm.php similarity index 97% rename from src/Form/CompanyForm.php rename to src/Form/AdminPages/CompanyForm.php index 27b9eca6..42328713 100644 --- a/src/Form/CompanyForm.php +++ b/src/Form/AdminPages/CompanyForm.php @@ -29,10 +29,11 @@ * */ -namespace App\Form; +namespace App\Form\AdminPages; use App\Entity\Base\NamedDBElement; +use App\Form\AdminPages\BaseEntityAdminForm; use Symfony\Component\Form\Extension\Core\Type\CheckboxType; use Symfony\Component\Form\Extension\Core\Type\EmailType; use Symfony\Component\Form\Extension\Core\Type\TelType; diff --git a/src/Form/ImportType.php b/src/Form/AdminPages/ImportType.php similarity index 97% rename from src/Form/ImportType.php rename to src/Form/AdminPages/ImportType.php index e4c61ca8..f3c6184a 100644 --- a/src/Form/ImportType.php +++ b/src/Form/AdminPages/ImportType.php @@ -29,7 +29,7 @@ * */ -namespace App\Form; +namespace App\Form\AdminPages; use App\Entity\Base\StructuralDBElement; @@ -71,7 +71,7 @@ class ImportType extends AbstractType 'disabled' => $disabled]) ->add('csv_separator', TextType::class, ['data' => ';', 'label' => 'import.csv_separator', 'disabled' => $disabled]); - if($data['entity_class'] instanceof StructuralDBElement) { + if($entity instanceof StructuralDBElement) { $builder-> add('parent', EntityType::class, ['class' => $data['entity_class'], 'choice_label' => 'full_path', 'attr' => ['class' => 'selectpicker', 'data-live-search' => true], 'required' => false, diff --git a/src/Form/AdminPages/MassCreationForm.php b/src/Form/AdminPages/MassCreationForm.php new file mode 100644 index 00000000..d8909de4 --- /dev/null +++ b/src/Form/AdminPages/MassCreationForm.php @@ -0,0 +1,81 @@ +security = $security; + } + + public function buildForm(FormBuilderInterface $builder, array $options) + { + + $data = $options['data']; + + //Disable import if user is not allowed to create elements. + $entity = new $data['entity_class'](); + $perm_name = "create"; + $disabled = ! $this->security->isGranted($perm_name, $entity); + + $builder + ->add('lines', TextareaType::class, ['data' => '', 'label' => 'mass_creation.lines', + 'disabled' => $disabled, 'required' => true, + 'attr' => ['placeholder' => 'mass_creation.lines.placeholder', 'rows' => 10]]); + if ($entity 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 + //Buttons + ->add('create', SubmitType::class, ['label' => 'mass_creation.btn', 'disabled' => $disabled]); + } +} \ No newline at end of file diff --git a/src/Form/StorelocationAdminForm.php b/src/Form/AdminPages/StorelocationAdminForm.php similarity index 95% rename from src/Form/StorelocationAdminForm.php rename to src/Form/AdminPages/StorelocationAdminForm.php index ef9dab18..6edf8f51 100644 --- a/src/Form/StorelocationAdminForm.php +++ b/src/Form/AdminPages/StorelocationAdminForm.php @@ -29,10 +29,11 @@ * */ -namespace App\Form; +namespace App\Form\AdminPages; use App\Entity\Base\NamedDBElement; +use App\Form\AdminPages\BaseEntityAdminForm; use Symfony\Component\Form\Extension\Core\Type\CheckboxType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\FormBuilderInterface; diff --git a/src/Services/EntityImporter.php b/src/Services/EntityImporter.php index a76e9955..12827ed4 100644 --- a/src/Services/EntityImporter.php +++ b/src/Services/EntityImporter.php @@ -32,6 +32,7 @@ namespace App\Services; +use App\Entity\Base\NamedDBElement; use App\Entity\Base\StructuralDBElement; use Doctrine\ORM\EntityManagerInterface; use Symfony\Bundle\MakerBundle\Str; @@ -65,6 +66,47 @@ class EntityImporter ]); } + /** + * Creates many entries at once, based on a (text) list of names. + * + * @param string $lines The list of names seperated by \n + * @param string $class_name The name of the class for which the entities should be created + * @param StructuralDBElement|null $parent The element which will be used as parent element for new elements. + * @return array An associative array containing an ConstraintViolationList and the entity name as key are returned, + * if an error happened during validation. When everything was successfull, the array should be empty. + */ + public function massCreation(string $lines, string $class_name, ?StructuralDBElement $parent) : array + { + //Expand every line to a single entry: + $names = explode("\n", $lines); + + $errors = array(); + + foreach ($names as $name) { + $name = trim($name); + /** @var $entity StructuralDBElement */ + //Create new element with given name + $entity = new $class_name(); + $entity->setName($name); + $entity->setParent($parent); + + //Validate entity + $tmp = $this->validator->validate($entity); + //If no error occured, write entry to DB: + if (count($tmp) === 0) { + $this->em->persist($entity); + } else { //Otherwise log error + dump($tmp); + $errors[$entity->getFullPath()] = $tmp; + } + } + + //Save changes to database + $this->em->flush(); + + return $errors; + } + /** * This methods deserializes the given file and saves it database. * The imported elements will be checked (validated) before written to database. @@ -96,7 +138,7 @@ class EntityImporter $tmp = $this->validator->validate($entity); //When no validation error occured, persist entity to database (cascade must be set in entity) - if ($tmp === null) { + if (count($errors) === 0) { $this->em->persist($entity); } else { //Log validation errors to global log. $errors[$entity->getFullPath()] = $tmp; diff --git a/templates/AdminPages/EntityAdminBase.html.twig b/templates/AdminPages/EntityAdminBase.html.twig index 7f971e72..f3d4e23a 100644 --- a/templates/AdminPages/EntityAdminBase.html.twig +++ b/templates/AdminPages/EntityAdminBase.html.twig @@ -45,6 +45,7 @@