Allow timetraveling on data structures admin pages.

This commit is contained in:
Jan Böhmer 2020-03-04 21:54:03 +01:00
parent f9bb2d57e9
commit 31290c070a
15 changed files with 125 additions and 67 deletions

View file

@ -79,7 +79,7 @@ class AttachmentTypeController extends BaseAdminController
} }
/** /**
* @Route("/{id}/edit", requirements={"id"="\d+"}, name="attachment_type_edit") * @Route("/{id}/edit/{timestamp}", requirements={"id"="\d+"}, name="attachment_type_edit")
* @Route("/{id}", requirements={"id"="\d+"}) * @Route("/{id}", requirements={"id"="\d+"})
* *
* @param AttachmentType $entity * @param AttachmentType $entity
@ -87,9 +87,9 @@ class AttachmentTypeController extends BaseAdminController
* @param EntityManagerInterface $em * @param EntityManagerInterface $em
* @return Response * @return Response
*/ */
public function edit(AttachmentType $entity, Request $request, EntityManagerInterface $em): Response public function edit(AttachmentType $entity, Request $request, EntityManagerInterface $em, ?string $timestamp = null): Response
{ {
return $this->_edit($entity, $request, $em); return $this->_edit($entity, $request, $em, $timestamp);
} }
/** /**

View file

@ -112,11 +112,23 @@ abstract class BaseAdminController extends AbstractController
} }
protected function _edit(AbstractNamedDBElement $entity, Request $request, EntityManagerInterface $em) : Response protected function _edit(AbstractNamedDBElement $entity, Request $request, EntityManagerInterface $em, ?string $timestamp = null) : Response
{ {
$this->denyAccessUnlessGranted('read', $entity); $this->denyAccessUnlessGranted('read', $entity);
$timeTravel_timestamp = null;
if ($timestamp !== null) {
//If the timestamp only contains numbers interpret it as unix timestamp
if (ctype_digit($timestamp)) {
$timeTravel_timestamp = new \DateTime();
$timeTravel_timestamp->setTimestamp((int) $timestamp);
} else { //Try to parse it via DateTime
$timeTravel_timestamp = new \DateTime($timestamp);
}
$this->timeTravel->revertEntityToTimestamp($entity, $timeTravel_timestamp);
}
$table = $this->dataTableFactory->createFromType(LogDataTable::class, [ $table = $this->dataTableFactory->createFromType(LogDataTable::class, [
'filter_elements' => $this->historyHelper->getAssociatedElements($entity), 'filter_elements' => $this->historyHelper->getAssociatedElements($entity),
'mode' => 'element_history' 'mode' => 'element_history'
@ -127,7 +139,10 @@ abstract class BaseAdminController extends AbstractController
return $table->getResponse(); return $table->getResponse();
} }
$form = $this->createForm($this->form_class, $entity, ['attachment_class' => $this->attachment_class]); $form = $this->createForm($this->form_class, $entity, [
'attachment_class' => $this->attachment_class,
'disabled' => $timeTravel_timestamp !== null ? true : null
]);
$form->handleRequest($request); $form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) { if ($form->isSubmitted() && $form->isValid()) {
@ -176,7 +191,8 @@ abstract class BaseAdminController extends AbstractController
'form' => $form->createView(), 'form' => $form->createView(),
'attachment_helper' => $this->attachmentHelper, 'attachment_helper' => $this->attachmentHelper,
'route_base' => $this->route_base, 'route_base' => $this->route_base,
'datatable' => $table 'datatable' => $table,
'timeTravel' => $timeTravel_timestamp
]); ]);
} }

View file

@ -79,7 +79,7 @@ class CategoryController extends BaseAdminController
} }
/** /**
* @Route("/{id}/edit", requirements={"id"="\d+"}, name="category_edit") * @Route("/{id}/edit/{timestamp}", requirements={"id"="\d+"}, name="category_edit")
* @Route("/{id}", requirements={"id"="\d+"}) * @Route("/{id}", requirements={"id"="\d+"})
* *
* @param Category $entity * @param Category $entity
@ -87,9 +87,9 @@ class CategoryController extends BaseAdminController
* @param EntityManagerInterface $em * @param EntityManagerInterface $em
* @return Response * @return Response
*/ */
public function edit(Category $entity, Request $request, EntityManagerInterface $em): Response public function edit(Category $entity, Request $request, EntityManagerInterface $em, ?string $timestamp = null): Response
{ {
return $this->_edit($entity, $request, $em); return $this->_edit($entity, $request, $em, $timestamp);
} }
/** /**

View file

@ -81,7 +81,7 @@ class CurrencyController extends BaseAdminController
} }
/** /**
* @Route("/{id}/edit", requirements={"id"="\d+"}, name="currency_edit") * @Route("/{id}/edit/{timestamp}", requirements={"id"="\d+"}, name="currency_edit")
* @Route("/{id}", requirements={"id"="\d+"}) * @Route("/{id}", requirements={"id"="\d+"})
* *
* @param Currency $entity * @param Currency $entity
@ -89,9 +89,9 @@ class CurrencyController extends BaseAdminController
* @param EntityManagerInterface $em * @param EntityManagerInterface $em
* @return Response * @return Response
*/ */
public function edit(Currency $entity, Request $request, EntityManagerInterface $em): Response public function edit(Currency $entity, Request $request, EntityManagerInterface $em, ?string $timestamp = null): Response
{ {
return $this->_edit($entity, $request, $em); return $this->_edit($entity, $request, $em, $timestamp);
} }
/** /**

View file

@ -79,7 +79,7 @@ class DeviceController extends BaseAdminController
} }
/** /**
* @Route("/{id}/edit", requirements={"id"="\d+"}, name="device_edit") * @Route("/{id}/edit/{timestamp}", requirements={"id"="\d+"}, name="device_edit")
* @Route("/{id}", requirements={"id"="\d+"}) * @Route("/{id}", requirements={"id"="\d+"})
* *
* @param Device $entity * @param Device $entity
@ -87,9 +87,9 @@ class DeviceController extends BaseAdminController
* @param EntityManagerInterface $em * @param EntityManagerInterface $em
* @return Response * @return Response
*/ */
public function edit(Device $entity, Request $request, EntityManagerInterface $em): Response public function edit(Device $entity, Request $request, EntityManagerInterface $em, ?string $timestamp = null): Response
{ {
return $this->_edit($entity, $request, $em); return $this->_edit($entity, $request, $em, $timestamp);
} }
/** /**

View file

@ -78,16 +78,16 @@ class FootprintController extends BaseAdminController
} }
/** /**
* @Route("/{id}/edit", requirements={"id"="\d+"}, name="footprint_edit") * @Route("/{id}/edit/{timestamp}", requirements={"id"="\d+"}, name="footprint_edit")
* @Route("/{id}", requirements={"id"="\d+"}) * @Route("/{id}", requirements={"id"="\d+"})
* @param Footprint $entity * @param Footprint $entity
* @param Request $request * @param Request $request
* @param EntityManagerInterface $em * @param EntityManagerInterface $em
* @return Response * @return Response
*/ */
public function edit(Footprint $entity, Request $request, EntityManagerInterface $em) public function edit(Footprint $entity, Request $request, EntityManagerInterface $em, ?string $timestamp = null)
{ {
return $this->_edit($entity, $request, $em); return $this->_edit($entity, $request, $em, $timestamp);
} }
/** /**

View file

@ -77,16 +77,16 @@ class ManufacturerController extends BaseAdminController
} }
/** /**
* @Route("/{id}/edit", requirements={"id"="\d+"}, name="manufacturer_edit") * @Route("/{id}/edit/{timestamp}", requirements={"id"="\d+"}, name="manufacturer_edit")
* @Route("/{id}", requirements={"id"="\d+"}) * @Route("/{id}", requirements={"id"="\d+"})
* @param Manufacturer $entity * @param Manufacturer $entity
* @param Request $request * @param Request $request
* @param EntityManagerInterface $em * @param EntityManagerInterface $em
* @return Response * @return Response
*/ */
public function edit(Manufacturer $entity, Request $request, EntityManagerInterface $em) public function edit(Manufacturer $entity, Request $request, EntityManagerInterface $em, ?string $timestamp = null)
{ {
return $this->_edit($entity, $request, $em); return $this->_edit($entity, $request, $em, $timestamp);
} }
/** /**

View file

@ -78,16 +78,16 @@ class MeasurementUnitController extends BaseAdminController
} }
/** /**
* @Route("/{id}/edit", requirements={"id"="\d+"}, name="measurement_unit_edit") * @Route("/{id}/edit/{timestamp}", requirements={"id"="\d+"}, name="measurement_unit_edit")
* @Route("/{id}", requirements={"id"="\d+"}) * @Route("/{id}", requirements={"id"="\d+"})
* @param MeasurementUnit $entity * @param MeasurementUnit $entity
* @param Request $request * @param Request $request
* @param EntityManagerInterface $em * @param EntityManagerInterface $em
* @return Response * @return Response
*/ */
public function edit(MeasurementUnit $entity, Request $request, EntityManagerInterface $em) public function edit(MeasurementUnit $entity, Request $request, EntityManagerInterface $em, ?string $timestamp = null)
{ {
return $this->_edit($entity, $request, $em); return $this->_edit($entity, $request, $em, $timestamp);
} }
/** /**

View file

@ -76,16 +76,16 @@ class StorelocationController extends BaseAdminController
} }
/** /**
* @Route("/{id}/edit", requirements={"id"="\d+"}, name="store_location_edit") * @Route("/{id}/edit/{timestamp}", requirements={"id"="\d+"}, name="store_location_edit")
* @Route("/{id}", requirements={"id"="\d+"}) * @Route("/{id}", requirements={"id"="\d+"})
* @param Storelocation $entity * @param Storelocation $entity
* @param Request $request * @param Request $request
* @param EntityManagerInterface $em * @param EntityManagerInterface $em
* @return Response * @return Response
*/ */
public function edit(Storelocation $entity, Request $request, EntityManagerInterface $em) public function edit(Storelocation $entity, Request $request, EntityManagerInterface $em, ?string $timestamp = null)
{ {
return $this->_edit($entity, $request, $em); return $this->_edit($entity, $request, $em, $timestamp);
} }
/** /**

View file

@ -77,16 +77,16 @@ class SupplierController extends BaseAdminController
} }
/** /**
* @Route("/{id}/edit", requirements={"id"="\d+"}, name="supplier_edit") * @Route("/{id}/edit/{timestamp}", requirements={"id"="\d+"}, name="supplier_edit")
* @Route("/{id}", requirements={"id"="\d+"}) * @Route("/{id}", requirements={"id"="\d+"})
* @param Supplier $entity * @param Supplier $entity
* @param Request $request * @param Request $request
* @param EntityManagerInterface $em * @param EntityManagerInterface $em
* @return Response * @return Response
*/ */
public function edit(Supplier $entity, Request $request, EntityManagerInterface $em) public function edit(Supplier $entity, Request $request, EntityManagerInterface $em, ?string $timestamp = null)
{ {
return $this->_edit($entity, $request, $em); return $this->_edit($entity, $request, $em, $timestamp);
} }
/** /**

View file

@ -67,7 +67,7 @@ class GroupController extends BaseAdminController
protected $attachment_class = GroupAttachment::class; protected $attachment_class = GroupAttachment::class;
/** /**
* @Route("/{id}/edit", requirements={"id"="\d+"}, name="group_edit") * @Route("/{id}/edit/{timestamp}", requirements={"id"="\d+"}, name="group_edit")
* @Route("/{id}/", requirements={"id"="\d+"}) * @Route("/{id}/", requirements={"id"="\d+"})
* *
* @param Group $entity * @param Group $entity
@ -75,9 +75,9 @@ class GroupController extends BaseAdminController
* @param EntityManagerInterface $em * @param EntityManagerInterface $em
* @return Response * @return Response
*/ */
public function edit(Group $entity, Request $request, EntityManagerInterface $em): Response public function edit(Group $entity, Request $request, EntityManagerInterface $em, ?string $timestamp = null): Response
{ {
return $this->_edit($entity, $request, $em); return $this->_edit($entity, $request, $em, $timestamp);
} }
/** /**

View file

@ -69,7 +69,7 @@ class UserController extends AdminPages\BaseAdminController
protected $attachment_class = UserAttachment::class; protected $attachment_class = UserAttachment::class;
/** /**
* @Route("/{id}/edit", requirements={"id"="\d+"}, name="user_edit") * @Route("/{id}/edit/{timestamp}", requirements={"id"="\d+"}, name="user_edit")
* @Route("/{id}/", requirements={"id"="\d+"}) * @Route("/{id}/", requirements={"id"="\d+"})
* @param User $entity * @param User $entity
* @param Request $request * @param Request $request
@ -77,7 +77,7 @@ class UserController extends AdminPages\BaseAdminController
* @return Response * @return Response
* @throws \Exception * @throws \Exception
*/ */
public function edit(User $entity, Request $request, EntityManagerInterface $em) public function edit(User $entity, Request $request, EntityManagerInterface $em, ?string $timestamp = null)
{ {
//Handle 2FA disabling //Handle 2FA disabling
@ -102,7 +102,7 @@ class UserController extends AdminPages\BaseAdminController
} }
} }
return $this->_edit($entity, $request, $em); return $this->_edit($entity, $request, $em, $timestamp);
} }
/** /**

View file

@ -250,6 +250,13 @@ class UserAdminForm extends AbstractType
'disabled' => ! $this->security->isGranted($is_new ? 'create' : 'edit', $entity), 'disabled' => ! $this->security->isGranted($is_new ? 'create' : 'edit', $entity),
]); ]);
$builder->add('log_comment', TextType::class, [
'label' => 'edit.log_comment',
'mapped' => false,
'required' => false,
'empty_data' => null,
]);
//Buttons //Buttons
$builder->add('save', SubmitType::class, [ $builder->add('save', SubmitType::class, [
'label' => $is_new ? 'user.create' : 'user.edit.save', 'label' => $is_new ? 'user.create' : 'user.edit.save',

View file

@ -132,12 +132,32 @@ class EntityURLGenerator
*/ */
public function timeTravelURL(AbstractDBElement $entity, \DateTime $dateTime): string public function timeTravelURL(AbstractDBElement $entity, \DateTime $dateTime): string
{ {
if ($entity instanceof Part) { $map = [
return $this->urlGenerator->generate('part_info', [ Part::class => 'part_info',
//As long we does not have own things for it use edit page
AttachmentType::class => 'attachment_type_edit',
Category::class => 'category_edit',
Device::class => 'device_edit',
Supplier::class => 'supplier_edit',
Manufacturer::class => 'manufacturer_edit',
Storelocation::class => 'store_location_edit',
Footprint::class => 'footprint_edit',
User::class => 'user_edit',
Currency::class => 'currency_edit',
MeasurementUnit::class => 'measurement_unit_edit',
Group::class => 'group_edit',
];
try {
return $this->urlGenerator->generate(
$this->mapToController($map, $entity),
[
'id' => $entity->getID(), 'id' => $entity->getID(),
'timestamp' => $dateTime->getTimestamp() 'timestamp' => $dateTime->getTimestamp()
]); ]
} );
} catch (EntityNotSupportedException $exception) {
if ($entity instanceof PartLot) { if ($entity instanceof PartLot) {
return $this->urlGenerator->generate('part_info', [ return $this->urlGenerator->generate('part_info', [
'id' => $entity->getPart()->getID(), 'id' => $entity->getPart()->getID(),
@ -162,6 +182,7 @@ class EntityURLGenerator
'timestamp' => $dateTime->getTimestamp() 'timestamp' => $dateTime->getTimestamp()
]); ]);
} }
}
//Otherwise throw an error //Otherwise throw an error
throw new EntityNotSupportedException('The given entity is not supported yet!'); throw new EntityNotSupportedException('The given entity is not supported yet!');

View file

@ -1,5 +1,13 @@
{% extends "main_card.html.twig" %} {% extends "main_card.html.twig" %}
{% block card_type %}
{% if timeTravel is defined and timeTravel is not null %}
bg-primary-striped text-white
{% else %}
bg-primary text-white
{% endif %}
{% endblock %}
{% form_theme form.log_comment 'bootstrap_4_layout.html.twig' %} {% form_theme form.log_comment 'bootstrap_4_layout.html.twig' %}
{% block card_content %} {% block card_content %}
@ -35,10 +43,16 @@
<legend> <legend>
{% if entity.ID %} {% if entity.ID %}
<strong>{% trans with {'%name': entity.name} %}edit.caption{% endtrans %}</strong> <strong>{% trans with {'%name': entity.name} %}edit.caption{% endtrans %}</strong>
{% if timeTravel is defined and timeTravel is not null %}
({{ timeTravel|format_datetime('short') }})
{% endif %}
{% else %} {% else %}
<strong>{% trans %}new.caption{% endtrans %}</strong> <strong>{% trans %}new.caption{% endtrans %}</strong>
{% endif %} {% endif %}
</legend> </legend>
{% if timeTravel is defined and timeTravel is not null %}
<b>{% trans with {'%timestamp%': timeTravel|format_datetime('short')} %}part.info.timetravel_hint{% endtrans %}</b>
{% endif %}
{{ form_errors(form) }} {{ form_errors(form) }}