diff --git a/src/Controller/AdminPages/AttachmentTypeController.php b/src/Controller/AdminPages/AttachmentTypeController.php index 8a62609b..b415251c 100644 --- a/src/Controller/AdminPages/AttachmentTypeController.php +++ b/src/Controller/AdminPages/AttachmentTypeController.php @@ -90,13 +90,14 @@ class AttachmentTypeController extends BaseAdminController /** * @Route("/new", name="attachment_type_new") + * @Route("/{id}/clone", name="attachment_type_clone") * @Route("/") * * @return Response */ - public function new(Request $request, EntityManagerInterface $em, EntityImporter $importer): Response + public function new(Request $request, EntityManagerInterface $em, EntityImporter $importer, ?AttachmentType $entity = null): Response { - return $this->_new($request, $em, $importer); + return $this->_new($request, $em, $importer, $entity); } /** diff --git a/src/Controller/AdminPages/BaseAdminController.php b/src/Controller/AdminPages/BaseAdminController.php index eda5e2d5..2d7ee815 100644 --- a/src/Controller/AdminPages/BaseAdminController.php +++ b/src/Controller/AdminPages/BaseAdminController.php @@ -219,10 +219,16 @@ abstract class BaseAdminController extends AbstractController ]); } - protected function _new(Request $request, EntityManagerInterface $em, EntityImporter $importer) + protected function _new(Request $request, EntityManagerInterface $em, EntityImporter $importer, ?AbstractNamedDBElement $entity = null) { - /** @var AbstractStructuralDBElement|User $new_entity */ - $new_entity = new $this->entity_class(); + $master_picture_backup = null; + if ($entity === null) { + /** @var AbstractStructuralDBElement|User $new_entity */ + $new_entity = new $this->entity_class(); + } else { + /** @var AbstractStructuralDBElement|User $new_entity */ + $new_entity = clone $entity; + } $this->denyAccessUnlessGranted('read', $new_entity); @@ -263,6 +269,7 @@ abstract class BaseAdminController extends AbstractController $this->commentHelper->setMessage($form['log_comment']->getData()); + dump($new_entity); $em->persist($new_entity); $em->flush(); $this->addFlash('success', 'entity.created_flash'); diff --git a/src/Controller/AdminPages/CategoryController.php b/src/Controller/AdminPages/CategoryController.php index 05ce64f6..a922b475 100644 --- a/src/Controller/AdminPages/CategoryController.php +++ b/src/Controller/AdminPages/CategoryController.php @@ -90,13 +90,14 @@ class CategoryController extends BaseAdminController /** * @Route("/new", name="category_new") + * @Route("/{id}/clone", name="category_clone") * @Route("/") * * @return Response */ - public function new(Request $request, EntityManagerInterface $em, EntityImporter $importer): Response + public function new(Request $request, EntityManagerInterface $em, EntityImporter $importer, ?Category $entity = null): Response { - return $this->_new($request, $em, $importer); + return $this->_new($request, $em, $importer, $entity); } /** diff --git a/src/Controller/AdminPages/CurrencyController.php b/src/Controller/AdminPages/CurrencyController.php index 757c9896..75bcb7dd 100644 --- a/src/Controller/AdminPages/CurrencyController.php +++ b/src/Controller/AdminPages/CurrencyController.php @@ -92,13 +92,14 @@ class CurrencyController extends BaseAdminController /** * @Route("/new", name="currency_new") + * @Route("/{id}/clone", name="currency_clone") * @Route("/") * * @return Response */ - public function new(Request $request, EntityManagerInterface $em, EntityImporter $importer): Response + public function new(Request $request, EntityManagerInterface $em, EntityImporter $importer, ?Currency $entity = null): Response { - return $this->_new($request, $em, $importer); + return $this->_new($request, $em, $importer, $entity); } /** diff --git a/src/Controller/AdminPages/DeviceController.php b/src/Controller/AdminPages/DeviceController.php index ad99243b..71ea2ae6 100644 --- a/src/Controller/AdminPages/DeviceController.php +++ b/src/Controller/AdminPages/DeviceController.php @@ -90,13 +90,14 @@ class DeviceController extends BaseAdminController /** * @Route("/new", name="device_new") + * @Route("/{id}/clone", name="device_clone") * @Route("/") * * @return Response */ - public function new(Request $request, EntityManagerInterface $em, EntityImporter $importer): Response + public function new(Request $request, EntityManagerInterface $em, EntityImporter $importer, ?Device $entity = null): Response { - return $this->_new($request, $em, $importer); + return $this->_new($request, $em, $importer, $entity); } /** diff --git a/src/Controller/AdminPages/FootprintController.php b/src/Controller/AdminPages/FootprintController.php index 42a653ce..1eec7ec6 100644 --- a/src/Controller/AdminPages/FootprintController.php +++ b/src/Controller/AdminPages/FootprintController.php @@ -90,13 +90,14 @@ class FootprintController extends BaseAdminController /** * @Route("/new", name="footprint_new") + * @Route("/{id}/clone", name="footprint_clone") * @Route("/") * * @return Response */ - public function new(Request $request, EntityManagerInterface $em, EntityImporter $importer): Response + public function new(Request $request, EntityManagerInterface $em, EntityImporter $importer, ?Footprint $entity = null): Response { - return $this->_new($request, $em, $importer); + return $this->_new($request, $em, $importer, $entity); } /** diff --git a/src/Controller/AdminPages/ManufacturerController.php b/src/Controller/AdminPages/ManufacturerController.php index 047b9b4f..c852ef9f 100644 --- a/src/Controller/AdminPages/ManufacturerController.php +++ b/src/Controller/AdminPages/ManufacturerController.php @@ -89,13 +89,14 @@ class ManufacturerController extends BaseAdminController /** * @Route("/new", name="manufacturer_new") + * @Route("/{id}/clone", name="manufacturer_clone") * @Route("/") * * @return Response */ - public function new(Request $request, EntityManagerInterface $em, EntityImporter $importer): Response + public function new(Request $request, EntityManagerInterface $em, EntityImporter $importer, ?Manufacturer $entity = null): Response { - return $this->_new($request, $em, $importer); + return $this->_new($request, $em, $importer, $entity); } /** diff --git a/src/Controller/AdminPages/MeasurementUnitController.php b/src/Controller/AdminPages/MeasurementUnitController.php index 7ada3e31..f47d4296 100644 --- a/src/Controller/AdminPages/MeasurementUnitController.php +++ b/src/Controller/AdminPages/MeasurementUnitController.php @@ -90,13 +90,14 @@ class MeasurementUnitController extends BaseAdminController /** * @Route("/new", name="measurement_unit_new") + * @Route("/{id}/clone", name="measurement_unit_clone") * @Route("/") * * @return Response */ - public function new(Request $request, EntityManagerInterface $em, EntityImporter $importer): Response + public function new(Request $request, EntityManagerInterface $em, EntityImporter $importer, ?MeasurementUnit $entity = null): Response { - return $this->_new($request, $em, $importer); + return $this->_new($request, $em, $importer, $entity); } /** diff --git a/src/Controller/AdminPages/StorelocationController.php b/src/Controller/AdminPages/StorelocationController.php index 703fe58a..bc8646c9 100644 --- a/src/Controller/AdminPages/StorelocationController.php +++ b/src/Controller/AdminPages/StorelocationController.php @@ -88,13 +88,14 @@ class StorelocationController extends BaseAdminController /** * @Route("/new", name="store_location_new") + * @Route("/{id}/clone", name="store_location_clone") * @Route("/") * * @return Response */ - public function new(Request $request, EntityManagerInterface $em, EntityImporter $importer): Response + public function new(Request $request, EntityManagerInterface $em, EntityImporter $importer, ?Storelocation $entity = null): Response { - return $this->_new($request, $em, $importer); + return $this->_new($request, $em, $importer, $entity); } /** diff --git a/src/Controller/AdminPages/SupplierController.php b/src/Controller/AdminPages/SupplierController.php index 8424f137..9e9e27dc 100644 --- a/src/Controller/AdminPages/SupplierController.php +++ b/src/Controller/AdminPages/SupplierController.php @@ -89,13 +89,14 @@ class SupplierController extends BaseAdminController /** * @Route("/new", name="supplier_new") + * @Route("/{id}/clone", name="supplier_clone") * @Route("/") * * @return Response */ - public function new(Request $request, EntityManagerInterface $em, EntityImporter $importer): Response + public function new(Request $request, EntityManagerInterface $em, EntityImporter $importer, ?Supplier $entity = null): Response { - return $this->_new($request, $em, $importer); + return $this->_new($request, $em, $importer, $entity); } /** diff --git a/src/Controller/GroupController.php b/src/Controller/GroupController.php index 1bbdf1b0..1fdc7ba1 100644 --- a/src/Controller/GroupController.php +++ b/src/Controller/GroupController.php @@ -81,13 +81,14 @@ class GroupController extends BaseAdminController /** * @Route("/new", name="group_new") + * @Route("/{id}/clone", name="group_clone") * @Route("/") * * @return Response */ - public function new(Request $request, EntityManagerInterface $em, EntityImporter $importer): Response + public function new(Request $request, EntityManagerInterface $em, EntityImporter $importer, ?Group $entity = null): Response { - return $this->_new($request, $em, $importer); + return $this->_new($request, $em, $importer, $entity); } /** diff --git a/src/Controller/UserController.php b/src/Controller/UserController.php index 4cd4419d..928b56d9 100644 --- a/src/Controller/UserController.php +++ b/src/Controller/UserController.php @@ -116,13 +116,14 @@ class UserController extends AdminPages\BaseAdminController /** * @Route("/new", name="user_new") + * @Route("/{id}/clone", name="user_clone") * @Route("/") * * @return Response */ - public function new(Request $request, EntityManagerInterface $em, EntityImporter $importer): Response + public function new(Request $request, EntityManagerInterface $em, EntityImporter $importer, ?User $entity = null): Response { - return $this->_new($request, $em, $importer); + return $this->_new($request, $em, $importer, $entity); } /** diff --git a/src/Form/Type/MasterPictureAttachmentType.php b/src/Form/Type/MasterPictureAttachmentType.php index 070bb80d..2f3c8979 100644 --- a/src/Form/Type/MasterPictureAttachmentType.php +++ b/src/Form/Type/MasterPictureAttachmentType.php @@ -43,11 +43,14 @@ declare(strict_types=1); namespace App\Form\Type; use App\Entity\Attachments\Attachment; +use App\Entity\Attachments\AttachmentContainingDBElement; use App\Entity\Contracts\HasMasterAttachmentInterface; use Doctrine\ORM\EntityRepository; use ReflectionClass; use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\ChoiceList\Loader\CallbackChoiceLoader; +use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\OptionsResolver\Options; use Symfony\Component\OptionsResolver\OptionsResolver; @@ -59,53 +62,42 @@ class MasterPictureAttachmentType extends AbstractType $resolver->setAllowedTypes('entity', HasMasterAttachmentInterface::class); $resolver->setDefaults([ - 'filter' => 'picture', - 'choice_translation_domain' => false, - 'attr' => [ - 'class' => 'selectpicker', - ], - 'choice_attr' => function (Options $options) { - return function ($choice, $key, $value) use ($options) { - /** @var Attachment $choice */ - $tmp = ['data-subtext' => $choice->getFilename() ?? 'URL']; + 'filter' => 'picture', + 'choice_translation_domain' => false, + 'attr' => [ + 'class' => 'selectpicker', + ], + 'choice_attr' => function (Options $options) { + return function ($choice, $key, $value) use ($options) { + /** @var Attachment $choice */ + $tmp = ['data-subtext' => $choice->getFilename() ?? 'URL']; - if ('picture' === $options['filter'] && ! $choice->isPicture()) { - $tmp += ['disabled' => 'disabled']; - } elseif ('3d_model' === $options['filter'] && ! $choice->is3DModel()) { - $tmp += ['disabled' => 'disabled']; - } + if ('picture' === $options['filter'] && ! $choice->isPicture()) { + $tmp += ['disabled' => 'disabled']; + } elseif ('3d_model' === $options['filter'] && ! $choice->is3DModel()) { + $tmp += ['disabled' => 'disabled']; + } - return $tmp; - }; - }, - 'choice_label' => 'name', - 'class' => function (Options $options) { - $short_class_name = (new ReflectionClass($options['entity']))->getShortName(); - //Category becomes CategoryAttachment - return 'App\\Entity\\Attachments\\'.$short_class_name.'Attachment'; - }, - 'query_builder' => function (Options $options) { - return function (EntityRepository $er) use ($options) { - $entity = $options['entity']; - if (null === $entity->getID()) { - //This query is always false, so we get empty results - return $er->createQueryBuilder('u')->where('0 = 2'); - } - - return $er->createQueryBuilder('u') - ->where('u.element = ?1') - ->andWhere("u.path <> ''") - ->orderBy('u.name', 'ASC') - ->setParameter(1, $entity); - }; - }, - ]); + return $tmp; + }; + }, + 'choice_label' => 'name', + 'choice_loader' => function (Options $options) { + return new CallbackChoiceLoader(function () use ($options) { + $entity = $options['entity']; + if (!$entity instanceof AttachmentContainingDBElement) { + throw new \RuntimeException('$entity must have Attachments! (be of type AttachmentContainingDBElement)'); + } + return $entity->getAttachments()->toArray(); + }); + } + ]); $resolver->setAllowedValues('filter', ['', 'picture', '3d_model']); } public function getParent() { - return EntityType::class; + return ChoiceType::class; } } diff --git a/src/Services/EntityURLGenerator.php b/src/Services/EntityURLGenerator.php index 2d553915..87c10b0c 100644 --- a/src/Services/EntityURLGenerator.php +++ b/src/Services/EntityURLGenerator.php @@ -318,6 +318,17 @@ class EntityURLGenerator { $map = [ Part::class => 'part_clone', + AttachmentType::class => 'attachment_type_clone', + Category::class => 'category_clone', + Device::class => 'device_clone', + Supplier::class => 'supplier_clone', + Manufacturer::class => 'manufacturer_clone', + Storelocation::class => 'store_location_clone', + Footprint::class => 'footprint_clone', + User::class => 'user_clone', + Currency::class => 'currency_clone', + MeasurementUnit::class => 'measurement_unit_clone', + Group::class => 'group_clone', ]; return $this->urlGenerator->generate($this->mapToController($map, $entity), ['id' => $entity->getID()]); diff --git a/templates/AdminPages/EntityAdminBase.html.twig b/templates/AdminPages/EntityAdminBase.html.twig index ef4d335c..514f9938 100644 --- a/templates/AdminPages/EntityAdminBase.html.twig +++ b/templates/AdminPages/EntityAdminBase.html.twig @@ -147,6 +147,7 @@ {# Only include on existing parts #} {% if entity.id %} + {{ include('AdminPages/_duplicate.html.twig') }} {{ include('AdminPages/_delete_form.html.twig') }} {% endif %} diff --git a/templates/AdminPages/_duplicate.html.twig b/templates/AdminPages/_duplicate.html.twig new file mode 100644 index 00000000..a55129a2 --- /dev/null +++ b/templates/AdminPages/_duplicate.html.twig @@ -0,0 +1,5 @@ +
\ No newline at end of file