mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2025-06-21 01:25:55 +02:00
Refactored Admin Page controllers a bit...
This commit is contained in:
parent
e7e73602a0
commit
a8786341d5
5 changed files with 190 additions and 96 deletions
|
@ -44,6 +44,7 @@ namespace App\Controller\AdminPages;
|
|||
|
||||
use App\Entity\Attachments\AttachmentType;
|
||||
use App\Entity\Attachments\AttachmentTypeAttachment;
|
||||
use App\Entity\Base\AbstractNamedDBElement;
|
||||
use App\Entity\Parameters\AttachmentTypeParameter;
|
||||
use App\Form\AdminPages\AttachmentTypeAdminForm;
|
||||
use App\Services\EntityExporter;
|
||||
|
@ -119,4 +120,15 @@ class AttachmentTypeController extends BaseAdminController
|
|||
{
|
||||
return $this->_exportEntity($entity, $exporter, $request);
|
||||
}
|
||||
|
||||
protected function deleteCheck(AbstractNamedDBElement $entity): bool
|
||||
{
|
||||
if ($entity instanceof AttachmentType) {
|
||||
if ($entity->getAttachmentsForType()->count() > 0) {
|
||||
$this->addFlash('error', 'entity.delete.must_not_contain_attachments');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@ namespace App\Controller\AdminPages;
|
|||
|
||||
use App\DataTables\LogDataTable;
|
||||
use App\Entity\Attachments\AttachmentType;
|
||||
use App\Entity\Base\AbstractDBElement;
|
||||
use App\Entity\Base\AbstractNamedDBElement;
|
||||
use App\Entity\Base\AbstractPartsContainingDBElement;
|
||||
use App\Entity\Base\AbstractStructuralDBElement;
|
||||
|
@ -139,11 +140,8 @@ abstract class BaseAdminController extends AbstractController
|
|||
$this->entityManager = $entityManager;
|
||||
}
|
||||
|
||||
protected function _edit(AbstractNamedDBElement $entity, Request $request, EntityManagerInterface $em, ?string $timestamp = null): Response
|
||||
protected function revertElementIfNeeded(AbstractDBElement $entity, ?string $timestamp): ?\DateTime
|
||||
{
|
||||
$this->denyAccessUnlessGranted('read', $entity);
|
||||
|
||||
$timeTravel_timestamp = null;
|
||||
if (null !== $timestamp) {
|
||||
$this->denyAccessUnlessGranted('@tools.timetravel');
|
||||
$this->denyAccessUnlessGranted('show_history', $entity);
|
||||
|
@ -155,7 +153,27 @@ abstract class BaseAdminController extends AbstractController
|
|||
$timeTravel_timestamp = new \DateTime($timestamp);
|
||||
}
|
||||
$this->timeTravel->revertEntityToTimestamp($entity, $timeTravel_timestamp);
|
||||
|
||||
return $timeTravel_timestamp;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform some additional actions, when the form was valid, but before the entity is saved.
|
||||
* @return bool Return true, to save entity normally, return false, to abort saving.
|
||||
*/
|
||||
protected function additionalActionEdit(FormInterface $form, AbstractNamedDBElement $entity): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function _edit(AbstractNamedDBElement $entity, Request $request, EntityManagerInterface $em, ?string $timestamp = null): Response
|
||||
{
|
||||
$this->denyAccessUnlessGranted('read', $entity);
|
||||
|
||||
$timeTravel_timestamp = $this->revertElementIfNeeded($entity, $timestamp);
|
||||
|
||||
|
||||
if ($this->isGranted('show_history', $entity)) {
|
||||
$table = $this->dataTableFactory->createFromType(
|
||||
|
@ -194,17 +212,7 @@ abstract class BaseAdminController extends AbstractController
|
|||
|
||||
$form->handleRequest($request);
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
//Check if we editing a user and if we need to change the password of it
|
||||
if ($entity instanceof User && ! empty($form['new_password']->getData())) {
|
||||
$password = $this->passwordEncoder->encodePassword($entity, $form['new_password']->getData());
|
||||
$entity->setPassword($password);
|
||||
//By default the user must change the password afterwards
|
||||
$entity->setNeedPwChange(true);
|
||||
|
||||
$event = new SecurityEvent($entity);
|
||||
$this->eventDispatcher->dispatch($event, SecurityEvents::PASSWORD_CHANGED);
|
||||
}
|
||||
|
||||
if ($this->additionalActionEdit($form, $entity)) {
|
||||
//Upload passed files
|
||||
$attachments = $form['attachments'];
|
||||
foreach ($attachments as $attachment) {
|
||||
|
@ -215,11 +223,17 @@ abstract class BaseAdminController extends AbstractController
|
|||
];
|
||||
|
||||
try {
|
||||
$this->attachmentSubmitHandler->handleFormSubmit($attachment->getData(), $attachment['file']->getData(), $options);
|
||||
$this->attachmentSubmitHandler->handleFormSubmit(
|
||||
$attachment->getData(),
|
||||
$attachment['file']->getData(),
|
||||
$options
|
||||
);
|
||||
} catch (AttachmentDownloadException $attachmentDownloadException) {
|
||||
$this->addFlash(
|
||||
'error',
|
||||
$this->translator->trans('attachment.download_failed').' '.$attachmentDownloadException->getMessage()
|
||||
$this->translator->trans(
|
||||
'attachment.download_failed'
|
||||
).' '.$attachmentDownloadException->getMessage()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -229,6 +243,7 @@ abstract class BaseAdminController extends AbstractController
|
|||
$em->persist($entity);
|
||||
$em->flush();
|
||||
$this->addFlash('success', 'entity.edit_flash');
|
||||
}
|
||||
|
||||
//Rebuild form, so it is based on the updated data. Important for the parent field!
|
||||
//We can not use dynamic form events here, because the parent entity list is build from database!
|
||||
|
@ -262,6 +277,15 @@ abstract class BaseAdminController extends AbstractController
|
|||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform some additional actions, when the form was valid, but before the entity is saved.
|
||||
* @return bool Return true, to save entity normally, return false, to abort saving.
|
||||
*/
|
||||
protected function additionalActionNew(FormInterface $form, AbstractNamedDBElement $entity): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function _new(Request $request, EntityManagerInterface $em, EntityImporter $importer, ?AbstractNamedDBElement $entity = null)
|
||||
{
|
||||
$master_picture_backup = null;
|
||||
|
@ -284,13 +308,9 @@ abstract class BaseAdminController extends AbstractController
|
|||
$form->handleRequest($request);
|
||||
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
if ($new_entity instanceof User && ! empty($form['new_password']->getData())) {
|
||||
$password = $this->passwordEncoder->encodePassword($new_entity, $form['new_password']->getData());
|
||||
$new_entity->setPassword($password);
|
||||
//By default the user must change the password afterwards
|
||||
$new_entity->setNeedPwChange(true);
|
||||
}
|
||||
|
||||
//Perform additional actions
|
||||
if ($this->additionalActionNew($form, $new_entity)) {
|
||||
//Upload passed files
|
||||
$attachments = $form['attachments'];
|
||||
foreach ($attachments as $attachment) {
|
||||
|
@ -301,11 +321,17 @@ abstract class BaseAdminController extends AbstractController
|
|||
];
|
||||
|
||||
try {
|
||||
$this->attachmentSubmitHandler->handleFormSubmit($attachment->getData(), $attachment['file']->getData(), $options);
|
||||
$this->attachmentSubmitHandler->handleFormSubmit(
|
||||
$attachment->getData(),
|
||||
$attachment['file']->getData(),
|
||||
$options
|
||||
);
|
||||
} catch (AttachmentDownloadException $attachmentDownloadException) {
|
||||
$this->addFlash(
|
||||
'error',
|
||||
$this->translator->trans('attachment.download_failed').' '.$attachmentDownloadException->getMessage()
|
||||
$this->translator->trans(
|
||||
'attachment.download_failed'
|
||||
).' '.$attachmentDownloadException->getMessage()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -318,6 +344,7 @@ abstract class BaseAdminController extends AbstractController
|
|||
|
||||
return $this->redirectToRoute($this->route_base.'_edit', ['id' => $new_entity->getID()]);
|
||||
}
|
||||
}
|
||||
|
||||
if ($form->isSubmitted() && ! $form->isValid()) {
|
||||
$this->addFlash('error', 'entity.created_flash.invalid');
|
||||
|
@ -382,6 +409,24 @@ abstract class BaseAdminController extends AbstractController
|
|||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs checks if the element can be deleted safely. Otherwise an flash message is added.
|
||||
* @param AbstractNamedDBElement $entity The element that should be checked.
|
||||
* @return bool True if the the element can be deleted, false if not
|
||||
*/
|
||||
protected function deleteCheck(AbstractNamedDBElement $entity): bool
|
||||
{
|
||||
if ($entity instanceof AbstractPartsContainingDBElement) {
|
||||
/** @var AbstractPartsContainingRepository $repo */
|
||||
$repo = $this->entityManager->getRepository($this->entity_class);
|
||||
if ($repo->getPartsCount($entity) > 0) {
|
||||
$this->addFlash('error', 'entity.delete.must_not_contain_parts');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function _delete(Request $request, AbstractNamedDBElement $entity, StructuralElementRecursionHelper $recursionHelper): RedirectResponse
|
||||
{
|
||||
$this->denyAccessUnlessGranted('delete', $entity);
|
||||
|
@ -389,33 +434,8 @@ abstract class BaseAdminController extends AbstractController
|
|||
if ($this->isCsrfTokenValid('delete'.$entity->getId(), $request->request->get('_token'))) {
|
||||
$entityManager = $this->getDoctrine()->getManager();
|
||||
|
||||
//Check if we can delete the part (it must not contain Parts)
|
||||
if ($entity instanceof AbstractPartsContainingDBElement) {
|
||||
/** @var AbstractPartsContainingRepository $repo */
|
||||
$repo = $this->entityManager->getRepository($this->entity_class);
|
||||
if ($repo->getPartsCount($entity) > 0) {
|
||||
$this->addFlash('error', 'entity.delete.must_not_contain_parts');
|
||||
return $this->redirectToRoute($this->route_base.'_new');
|
||||
}
|
||||
} elseif ($entity instanceof AttachmentType) {
|
||||
if ($entity->getAttachmentsForType()->count() > 0) {
|
||||
$this->addFlash('error', 'entity.delete.must_not_contain_attachments');
|
||||
return $this->redirectToRoute($this->route_base.'_new');
|
||||
}
|
||||
} elseif ($entity instanceof Currency) {
|
||||
if ($entity->getPricedetails()->count() > 0) {
|
||||
$this->addFlash('error', 'entity.delete.must_not_contain_prices');
|
||||
return $this->redirectToRoute($this->route_base.'_new');
|
||||
}
|
||||
} elseif ($entity instanceof Group) {
|
||||
if ($entity->getUsers()->count() > 0) {
|
||||
$this->addFlash('error', 'entity.delete.must_not_contain_users');
|
||||
return $this->redirectToRoute($this->route_base.'_new');
|
||||
}
|
||||
} elseif ($entity instanceof User) {
|
||||
//TODO: Find a better solution
|
||||
$this->addFlash('error', 'Currently it is not possible to delete a user, as this would break the log... This will be implemented later...');
|
||||
return $this->redirectToRoute($this->route_base.'_new');
|
||||
if (!$this->deleteCheck($entity)) {
|
||||
return $this->redirectToRoute($this->route_base.'_edit', ['id' => $entity->getID()]);
|
||||
}
|
||||
|
||||
//Check if we need to remove recursively
|
||||
|
@ -452,18 +472,14 @@ abstract class BaseAdminController extends AbstractController
|
|||
protected function _exportAll(EntityManagerInterface $em, EntityExporter $exporter, Request $request): Response
|
||||
{
|
||||
$entity = new $this->entity_class();
|
||||
|
||||
$this->denyAccessUnlessGranted('read', $entity);
|
||||
|
||||
$entities = $em->getRepository($this->entity_class)->findAll();
|
||||
|
||||
return $exporter->exportEntityFromRequest($entities, $request);
|
||||
}
|
||||
|
||||
protected function _exportEntity(AbstractNamedDBElement $entity, EntityExporter $exporter, Request $request): \Symfony\Component\HttpFoundation\Response
|
||||
{
|
||||
$this->denyAccessUnlessGranted('read', $entity);
|
||||
|
||||
return $exporter->exportEntityFromRequest($entity, $request);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,6 +43,7 @@ declare(strict_types=1);
|
|||
namespace App\Controller\AdminPages;
|
||||
|
||||
use App\Entity\Attachments\CurrencyAttachment;
|
||||
use App\Entity\Base\AbstractNamedDBElement;
|
||||
use App\Entity\Parameters\CurrencyParameter;
|
||||
use App\Entity\PriceInformations\Currency;
|
||||
use App\Form\AdminPages\CurrencyAdminForm;
|
||||
|
@ -121,4 +122,16 @@ class CurrencyController extends BaseAdminController
|
|||
{
|
||||
return $this->_exportEntity($entity, $exporter, $request);
|
||||
}
|
||||
|
||||
public function deleteCheck(AbstractNamedDBElement $entity): bool
|
||||
{
|
||||
if ($entity instanceof Currency) {
|
||||
if ($entity->getPricedetails()->count() > 0) {
|
||||
$this->addFlash('error', 'entity.delete.must_not_contain_prices');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@ namespace App\Controller;
|
|||
|
||||
use App\Controller\AdminPages\BaseAdminController;
|
||||
use App\Entity\Attachments\GroupAttachment;
|
||||
use App\Entity\Base\AbstractNamedDBElement;
|
||||
use App\Entity\Parameters\GroupParameter;
|
||||
use App\Entity\UserSystem\Group;
|
||||
use App\Form\AdminPages\GroupAdminForm;
|
||||
|
@ -120,4 +121,16 @@ class GroupController extends BaseAdminController
|
|||
{
|
||||
return $this->_exportEntity($entity, $exporter, $request);
|
||||
}
|
||||
|
||||
public function deleteCheck(AbstractNamedDBElement $entity): bool
|
||||
{
|
||||
if ($entity instanceof Group) {
|
||||
if ($entity->getUsers()->count() > 0) {
|
||||
$this->addFlash('error', 'entity.delete.must_not_contain_users');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@ namespace App\Controller;
|
|||
|
||||
use App\DataTables\LogDataTable;
|
||||
use App\Entity\Attachments\UserAttachment;
|
||||
use App\Entity\Base\AbstractNamedDBElement;
|
||||
use App\Entity\UserSystem\User;
|
||||
use App\Events\SecurityEvent;
|
||||
use App\Events\SecurityEvents;
|
||||
|
@ -56,6 +57,7 @@ use Doctrine\ORM\EntityManagerInterface;
|
|||
use InvalidArgumentException;
|
||||
use Omines\DataTablesBundle\DataTableFactory;
|
||||
use Symfony\Component\Asset\Packages;
|
||||
use Symfony\Component\Form\FormInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
@ -74,6 +76,21 @@ class UserController extends AdminPages\BaseAdminController
|
|||
//Just define a value here to prevent error. It is not used.
|
||||
protected $parameter_class = 'not used';
|
||||
|
||||
protected function additionalActionEdit(FormInterface $form, AbstractNamedDBElement $entity): bool
|
||||
{
|
||||
//Check if we editing a user and if we need to change the password of it
|
||||
if ($entity instanceof User && !empty($form['new_password']->getData())) {
|
||||
$password = $this->passwordEncoder->encodePassword($entity, $form['new_password']->getData());
|
||||
$entity->setPassword($password);
|
||||
//By default the user must change the password afterwards
|
||||
$entity->setNeedPwChange(true);
|
||||
|
||||
$event = new SecurityEvent($entity);
|
||||
$this->eventDispatcher->dispatch($event, SecurityEvents::PASSWORD_CHANGED);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/{id}/edit/{timestamp}", requirements={"id"="\d+"}, name="user_edit")
|
||||
* @Route("/{id}/", requirements={"id"="\d+"})
|
||||
|
@ -113,6 +130,18 @@ class UserController extends AdminPages\BaseAdminController
|
|||
return $this->_edit($entity, $request, $em, $timestamp);
|
||||
}
|
||||
|
||||
protected function additionalActionNew(FormInterface $form, AbstractNamedDBElement $entity): bool
|
||||
{
|
||||
if ($entity instanceof User && ! empty($form['new_password']->getData())) {
|
||||
$password = $this->passwordEncoder->encodePassword($entity, $form['new_password']->getData());
|
||||
$entity->setPassword($password);
|
||||
//By default the user must change the password afterwards
|
||||
$entity->setNeedPwChange(true);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/new", name="user_new")
|
||||
* @Route("/{id}/clone", name="user_clone")
|
||||
|
@ -125,6 +154,17 @@ class UserController extends AdminPages\BaseAdminController
|
|||
return $this->_new($request, $em, $importer, $entity);
|
||||
}
|
||||
|
||||
protected function deleteCheck(AbstractNamedDBElement $entity): bool
|
||||
{
|
||||
if ($entity instanceof User) {
|
||||
//TODO: Find a better solution
|
||||
$this->addFlash('error', 'Currently it is not possible to delete a user, as this would break the log... This will be implemented later...');
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/{id}", name="user_delete", methods={"DELETE"}, requirements={"id"="\d+"})
|
||||
*
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue