Added possibility to add/edit attachments on Admin pages.

This commit is contained in:
Jan Böhmer 2019-09-24 18:28:35 +02:00
parent 97cb91a3b2
commit eb1d8fd4e4
28 changed files with 247 additions and 25 deletions

View file

@ -33,6 +33,7 @@ namespace App\Controller\AdminPages;
use App\Entity\Attachments\AttachmentType;
use App\Entity\Attachments\AttachmentTypeAttachment;
use App\Form\AdminPages\BaseEntityAdminForm;
use App\Services\EntityExporter;
use App\Services\EntityImporter;
@ -53,6 +54,7 @@ class AttachmentTypeController extends BaseAdminController
protected $twig_template = 'AdminPages/AttachmentTypeAdmin.html.twig';
protected $form_class = BaseEntityAdminForm::class;
protected $route_base = 'attachment_type';
protected $attachment_class = AttachmentTypeAttachment::class;
/**
* @Route("/{id}/edit", requirements={"id"="\d+"}, name="attachment_type_edit")

View file

@ -36,11 +36,13 @@ use App\Entity\Base\StructuralDBElement;
use App\Entity\UserSystem\User;
use App\Form\AdminPages\ImportType;
use App\Form\AdminPages\MassCreationForm;
use App\Services\AttachmentHelper;
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\Form\FormInterface;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Encoder\PasswordEncoderInterface;
@ -56,19 +58,26 @@ abstract class BaseAdminController extends AbstractController
protected $form_class = '';
protected $twig_template = '';
protected $route_base = '';
protected $attachment_class = '';
protected $passwordEncoder;
protected $translator;
protected $attachmentHelper;
public function __construct(TranslatorInterface $translator, UserPasswordEncoderInterface $passwordEncoder)
public function __construct(TranslatorInterface $translator, UserPasswordEncoderInterface $passwordEncoder, AttachmentHelper $attachmentHelper)
{
if ($this->entity_class === '' || $this->form_class === '' || $this->twig_template === '' || $this->route_base === '') {
throw new \InvalidArgumentException('You have to override the $entity_class, $form_class, $route_base and $twig_template value in your subclasss!');
}
if ($this->attachment_class === '') {
throw new \InvalidArgumentException('You have to override the $attachment_class value in your subclass!');
}
$this->translator = $translator;
$this->passwordEncoder = $passwordEncoder;
$this->attachmentHelper = $attachmentHelper;
}
protected function _edit(NamedDBElement $entity, Request $request, EntityManagerInterface $em)
@ -76,7 +85,7 @@ abstract class BaseAdminController extends AbstractController
$this->denyAccessUnlessGranted('read', $entity);
$form = $this->createForm($this->form_class, $entity);
$form = $this->createForm($this->form_class, $entity, ['attachment_class' => $this->attachment_class]);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
@ -88,20 +97,28 @@ abstract class BaseAdminController extends AbstractController
$entity->setNeedPwChange(true);
}
//Upload passed files
$attachments = $form['attachments'];
foreach ($attachments as $attachment) {
/** @var $attachment FormInterface */
$this->attachmentHelper->upload( $attachment->getData(), $attachment['file']->getData());
}
$em->persist($entity);
$em->flush();
$this->addFlash('success', $this->translator->trans('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!
$form = $this->createForm($this->form_class, $entity);
$form = $this->createForm($this->form_class, $entity, ['attachment_class' => $this->attachment_class]);
} elseif ($form->isSubmitted() && ! $form->isValid()) {
$this->addFlash('error', $this->translator->trans('entity.edit_flash.invalid'));
}
return $this->render($this->twig_template, [
'entity' => $entity,
'form' => $form->createView()
'form' => $form->createView(),
'attachment_helper' => $this->attachmentHelper
]);
}
@ -113,7 +130,7 @@ abstract class BaseAdminController extends AbstractController
$this->denyAccessUnlessGranted('read', $new_entity);
//Basic edit form
$form = $this->createForm($this->form_class, $new_entity);
$form = $this->createForm($this->form_class, $new_entity, ['attachment_class' => $this->attachment_class]);
$form->handleRequest($request);
@ -124,6 +141,14 @@ abstract class BaseAdminController extends AbstractController
//By default the user must change the password afterwards
$new_entity->setNeedPwChange(true);
}
//Upload passed files
$attachments = $form['attachments'];
foreach ($attachments as $attachment) {
/** @var $attachment FormInterface */
$this->attachmentHelper->upload( $attachment->getData(), $attachment['file']->getData());
}
$em->persist($new_entity);
$em->flush();
$this->addFlash('success', $this->translator->trans('entity.created_flash'));
@ -178,7 +203,8 @@ abstract class BaseAdminController extends AbstractController
'entity' => $new_entity,
'form' => $form->createView(),
'import_form' => $import_form->createView(),
'mass_creation_form' => $mass_creation_form->createView()
'mass_creation_form' => $mass_creation_form->createView(),
'attachment_helper' => $this->attachmentHelper
]);
}

View file

@ -32,6 +32,7 @@
namespace App\Controller\AdminPages;
use App\Entity\Attachments\CategoryAttachment;
use App\Entity\Parts\Category;
use App\Form\AdminPages\CategoryAdminForm;
use App\Services\EntityExporter;
@ -53,6 +54,7 @@ class CategoryController extends BaseAdminController
protected $twig_template = 'AdminPages/CategoryAdmin.html.twig';
protected $form_class = CategoryAdminForm::class;
protected $route_base = 'category';
protected $attachment_class = CategoryAttachment::class;
/**
* @Route("/{id}/edit", requirements={"id"="\d+"}, name="category_edit")

View file

@ -32,6 +32,7 @@
namespace App\Controller\AdminPages;
use App\Entity\Attachments\CurrencyAttachment;
use App\Entity\PriceInformations\Currency;
use App\Form\AdminPages\CurrencyAdminForm;
use App\Services\EntityExporter;
@ -54,6 +55,7 @@ class CurrencyController extends BaseAdminController
protected $twig_template = 'AdminPages/CurrencyAdmin.html.twig';
protected $form_class = CurrencyAdminForm::class;
protected $route_base = 'currency';
protected $attachment_class = CurrencyAttachment::class;
/**
* @Route("/{id}/edit", requirements={"id"="\d+"}, name="currency_edit")

View file

@ -32,6 +32,7 @@
namespace App\Controller\AdminPages;
use App\Entity\Attachments\DeviceAttachment;
use App\Entity\Devices\Device;
use App\Form\AdminPages\BaseEntityAdminForm;
use App\Services\EntityExporter;
@ -53,6 +54,7 @@ class DeviceController extends BaseAdminController
protected $twig_template = 'AdminPages/DeviceAdmin.html.twig';
protected $form_class = BaseEntityAdminForm::class;
protected $route_base = 'device';
protected $attachment_class = DeviceAttachment::class;
/**
* @Route("/{id}/edit", requirements={"id"="\d+"}, name="device_edit")

View file

@ -34,6 +34,7 @@ namespace App\Controller\AdminPages;
use App\Entity\Attachments\AttachmentType;
use App\Entity\Attachments\FootprintAttachment;
use App\Entity\Parts\Footprint;
use App\Form\AdminPages\BaseEntityAdminForm;
use App\Services\EntityExporter;
@ -56,6 +57,7 @@ class FootprintController extends BaseAdminController
protected $twig_template = 'AdminPages/FootprintAdmin.html.twig';
protected $form_class = BaseEntityAdminForm::class;
protected $route_base = 'footprint';
protected $attachment_class = FootprintAttachment::class;
/**
* @Route("/{id}/edit", requirements={"id"="\d+"}, name="footprint_edit")

View file

@ -32,6 +32,7 @@
namespace App\Controller\AdminPages;
use App\Entity\Attachments\ManufacturerAttachment;
use App\Entity\Parts\Manufacturer;
use App\Entity\Parts\Supplier;
use App\Form\AdminPages\CompanyForm;
@ -55,6 +56,7 @@ class ManufacturerController extends BaseAdminController
protected $twig_template = 'AdminPages/ManufacturerAdmin.html.twig';
protected $form_class = CompanyForm::class;
protected $route_base = 'manufacturer';
protected $attachment_class = ManufacturerAttachment::class;
/**
* @Route("/{id}/edit", requirements={"id"="\d+"}, name="manufacturer_edit")

View file

@ -33,6 +33,7 @@ namespace App\Controller\AdminPages;
use App\Entity\Attachments\AttachmentType;
use App\Entity\Attachments\MeasurementUnitAttachment;
use App\Entity\Parts\MeasurementUnit;
use App\Form\AdminPages\MeasurementUnitAdminForm;
use App\Services\EntityExporter;
@ -55,6 +56,7 @@ class MeasurementUnitController extends BaseAdminController
protected $twig_template = 'AdminPages/MeasurementUnitAdmin.html.twig';
protected $form_class = MeasurementUnitAdminForm::class;
protected $route_base = 'measurement_unit';
protected $attachment_class = MeasurementUnitAttachment::class;
/**
* @Route("/{id}/edit", requirements={"id"="\d+"}, name="measurement_unit_edit")

View file

@ -55,6 +55,7 @@ class StorelocationController extends BaseAdminController
protected $twig_template = 'AdminPages/StorelocationAdmin.html.twig';
protected $form_class = StorelocationAdminForm::class;
protected $route_base = 'store_location';
protected $attachment_class = StorelocationAdminForm::class;
/**
* @Route("/{id}/edit", requirements={"id"="\d+"}, name="store_location_edit")

View file

@ -32,6 +32,7 @@
namespace App\Controller\AdminPages;
use App\Entity\Attachments\SupplierAttachment;
use App\Entity\Parts\Supplier;
use App\Form\AdminPages\SupplierForm;
use App\Services\EntityExporter;
@ -54,6 +55,7 @@ class SupplierController extends BaseAdminController
protected $twig_template = 'AdminPages/SupplierAdmin.html.twig';
protected $form_class = SupplierForm::class;
protected $route_base = 'supplier';
protected $attachment_class = SupplierAttachment::class;
/**
* @Route("/{id}/edit", requirements={"id"="\d+"}, name="supplier_edit")

View file

@ -33,6 +33,7 @@ namespace App\Controller;
use App\Controller\AdminPages\BaseAdminController;
use App\Entity\Attachments\GroupAttachment;
use App\Entity\UserSystem\Group;
use App\Form\AdminPages\GroupAdminForm;
use App\Services\EntityExporter;
@ -52,6 +53,7 @@ class GroupController extends BaseAdminController
protected $twig_template = 'AdminPages/GroupAdmin.html.twig';
protected $form_class = GroupAdminForm::class;
protected $route_base = 'group';
protected $attachment_class = GroupAttachment::class;
/**
* @Route("/{id}/edit", requirements={"id"="\d+"}, name="group_edit")

View file

@ -30,6 +30,7 @@
namespace App\Controller;
use App\Entity\Attachments\AttachmentType;
use App\Entity\Attachments\UserAttachment;
use App\Entity\UserSystem\User;
use App\Form\Permissions\PermissionsType;
use App\Form\UserAdminForm;
@ -62,6 +63,7 @@ class UserController extends AdminPages\BaseAdminController
protected $twig_template = 'AdminPages/UserAdmin.html.twig';
protected $form_class = UserAdminForm::class;
protected $route_base = 'user';
protected $attachment_class = UserAttachment::class;
/**

View file

@ -67,7 +67,7 @@ class AttachmentType extends StructuralDBElement
{
/**
* @var Collection|AttachmentTypeAttachment[]
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\AttachmentTypeAttachment", mappedBy="element")
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\AttachmentTypeAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
*/
protected $attachments;

View file

@ -78,7 +78,7 @@ class Device extends PartsContainingDBElement
/**
* @var Collection|DeviceAttachment[]
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\DeviceAttachment", mappedBy="element")
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\DeviceAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
*/
protected $attachments;

View file

@ -68,7 +68,7 @@ class Category extends PartsContainingDBElement
/**
* @var Collection|CategoryAttachment[]
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\CategoryAttachment", mappedBy="element")
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\CategoryAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
*/
protected $attachments;

View file

@ -77,7 +77,7 @@ class Footprint extends PartsContainingDBElement
{
/**
* @var Collection|FootprintAttachment[]
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\FootprintAttachment", mappedBy="element")
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\FootprintAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
*/
protected $attachments;

View file

@ -77,7 +77,7 @@ class Manufacturer extends Company
{
/**
* @var Collection|ManufacturerAttachment[]
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\ManufacturerAttachment", mappedBy="element")
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\ManufacturerAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
*/
protected $attachments;

View file

@ -54,7 +54,7 @@ class MeasurementUnit extends PartsContainingDBElement
/**
* @var Collection|MeasurementUnitAttachment[]
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\MeasurementUnitAttachment", mappedBy="element")
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\MeasurementUnitAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
*/
protected $attachments;

View file

@ -78,7 +78,7 @@ class Storelocation extends PartsContainingDBElement
/**
* @var Collection|StorelocationAttachment[]
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\StorelocationAttachment", mappedBy="element")
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\StorelocationAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
*/
protected $attachments;

View file

@ -80,7 +80,7 @@ class Supplier extends Company
{
/**
* @var Collection|SupplierAttachment[]
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\ManufacturerAttachment", mappedBy="element")
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\SupplierAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
*/
protected $attachments;

View file

@ -54,7 +54,7 @@ class Currency extends StructuralDBElement
/**
* @var Collection|CurrencyAttachment[]
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\CurrencyAttachment", mappedBy="element")
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\CurrencyAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
*/
protected $attachments;

View file

@ -50,7 +50,7 @@ class Group extends StructuralDBElement implements HasPermissionsInterface
/**
* @var Collection|GroupAttachment[]
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\ManufacturerAttachment", mappedBy="element")
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\ManufacturerAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
*/
protected $attachments;

View file

@ -90,7 +90,7 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe
/**
* @var Collection|UserAttachment[]
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\UserAttachment", mappedBy="element")
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\UserAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
*/
protected $attachments;

View file

@ -32,8 +32,12 @@
namespace App\Form\AdminPages;
use App\Entity\Attachments\Attachment;
use App\Entity\Attachments\FootprintAttachment;
use App\Entity\Attachments\PartAttachment;
use App\Entity\Base\NamedDBElement;
use App\Entity\Base\StructuralDBElement;
use App\Form\AttachmentFormType;
use App\Form\Type\StructuralEntityType;
use FOS\CKEditorBundle\Form\Type\CKEditorType;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
@ -41,10 +45,12 @@ use Symfony\Component\DependencyInjection\ParameterBag\ContainerBagInterface;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\Extension\Core\Type\ResetType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Translation\Reader\TranslationReader;
use Symfony\Contracts\Translation\TranslatorInterface;
@ -63,6 +69,11 @@ class BaseEntityAdminForm extends AbstractType
$this->trans = $trans;
}
public function configureOptions(OptionsResolver $resolver)
{
parent::configureOptions($resolver); // TODO: Change the autogenerated stub
$resolver->setRequired('attachment_class');
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
@ -92,6 +103,18 @@ class BaseEntityAdminForm extends AbstractType
$this->additionalFormElements($builder, $options, $entity);
//Attachment section
$builder->add('attachments', CollectionType::class, [
'entry_type' => AttachmentFormType::class,
'allow_add' => true,
'allow_delete' => true,
'label' => false,
'entry_options' => [
'data_class' => $options['attachment_class'],
],
'by_reference' => false
]);
//Buttons
$builder->add('save', SubmitType::class, [
'label' => $is_new ? $this->trans->trans('entity.create') : $this->trans->trans('entity.edit.save'),

View file

@ -44,6 +44,7 @@ use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\Extension\Core\Type\LanguageType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
@ -52,6 +53,7 @@ use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\TimezoneType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Validator\Constraints\Length;
use Symfony\Contracts\Translation\TranslatorInterface;
@ -68,6 +70,11 @@ class UserAdminForm extends AbstractType
$this->trans = $trans;
}
public function configureOptions(OptionsResolver $resolver)
{
parent::configureOptions($resolver); // TODO: Change the autogenerated stub
$resolver->setRequired('attachment_class');
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
@ -182,6 +189,18 @@ class UserAdminForm extends AbstractType
$this->additionalFormElements($builder, $options, $entity);
//Attachment section
$builder->add('attachments', CollectionType::class, [
'entry_type' => AttachmentFormType::class,
'allow_add' => true,
'allow_delete' => true,
'label' => false,
'entry_options' => [
'data_class' => $options['attachment_class'],
],
'by_reference' => false
]);
//Buttons
$builder->add('save', SubmitType::class, [
'label' => $is_new ? $this->trans->trans('user.create') : $this->trans->trans('user.edit.save'),

View file

@ -33,7 +33,21 @@ namespace App\Services;
use App\Entity\Attachments\Attachment;
use App\Entity\Attachments\AttachmentTypeAttachment;
use App\Entity\Attachments\CategoryAttachment;
use App\Entity\Attachments\CurrencyAttachment;
use App\Entity\Attachments\DeviceAttachment;
use App\Entity\Attachments\FootprintAttachment;
use App\Entity\Attachments\GroupAttachment;
use App\Entity\Attachments\ManufacturerAttachment;
use App\Entity\Attachments\MeasurementUnitAttachment;
use App\Entity\Attachments\PartAttachment;
use App\Entity\Attachments\StorelocationAttachment;
use App\Entity\Attachments\SupplierAttachment;
use App\Entity\Attachments\UserAttachment;
use App\Entity\Parts\Part;
use App\Entity\UserSystem\Group;
use App\Entity\UserSystem\User;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\HttpFoundation\File\UploadedFile;
@ -46,6 +60,10 @@ class AttachmentHelper
*/
protected $base_path;
protected $footprints_path;
protected $footprints_3d_path;
public function __construct(ParameterBagInterface $params, KernelInterface $kernel)
{
$tmp_base_path = $params->get('media_directory');
@ -58,6 +76,10 @@ class AttachmentHelper
} else {
$this->base_path = realpath($kernel->getProjectDir() . DIRECTORY_SEPARATOR . $tmp_base_path);
}
$this->footprints_path = realpath($kernel->getProjectDir() . "/public/img/footprints");
//TODO
$this->footprints_3d_path = "TODO";
}
/**
@ -91,11 +113,15 @@ class AttachmentHelper
*/
public function placeholderToRealPath(string $placeholder_path) : string
{
//The new attachments use %MEDIA% as placeholders, which is the directory set in media_directory
$placeholder_path = str_replace("%MEDIA%", $this->base_path, $placeholder_path);
$placeholders = ["%MEDIA%", "%BASE%/data/media", "%FOOTPRINTS%", "%FOOTPRINTS_3D"];
$targets = [$this->base_path, $this->base_path, $this->footprints_path, $this->footprints_3d_path];
dump($placeholder_path);
//The new attachments use %MEDIA% as placeholders, which is the directory set in media_directory
//Older path entries are given via %BASE% which was the project root
$placeholder_path = str_replace("%BASE%/data/media", $this->base_path, $placeholder_path);
$placeholder_path = str_replace($placeholders, $targets, $placeholder_path);
dump($placeholder_path);
//Normalize path
$placeholder_path = str_replace('\\', '/', $placeholder_path);
@ -207,7 +233,12 @@ class AttachmentHelper
*/
public function generateFolderForAttachment(Attachment $attachment) : string
{
$mapping = [PartAttachment::class => 'part'];
$mapping = [PartAttachment::class => 'part', AttachmentTypeAttachment::class => 'attachment_type',
CategoryAttachment::class => 'category', CurrencyAttachment::class => 'currency',
DeviceAttachment::class => 'device', FootprintAttachment::class => 'footprint',
GroupAttachment::class => 'group', ManufacturerAttachment::class => 'manufacturer',
MeasurementUnitAttachment::class => 'measurement_unit', StorelocationAttachment::class => 'storelocation',
SupplierAttachment::class => 'supplier', UserAttachment::class => 'user'];
$path = $this->base_path . DIRECTORY_SEPARATOR . $mapping[get_class($attachment)] . DIRECTORY_SEPARATOR . $attachment->getElement()->getID();
return $path;

View file

@ -57,16 +57,20 @@
{{ form_start(form) }}
{% if block('additional_pills') is not empty %}
<ul class="nav nav-pills mb-2">
<li class="nav-item"><a data-toggle="tab" class="nav-link link-anchor active" href="#home_common">{% trans %}admin.common{% endtrans %}</a></li>
<li class="nav-item">
<a data-toggle="tab" class="nav-link link-anchor active" href="#common">{% trans %}admin.common{% endtrans %}</a>
</li>
{% block additional_pills %}{% endblock %}
<li class="nav-item">
<a data-toggle="tab" class="nav-link link-anchor" href="#attachments">{% trans %}admin.attachments{% endtrans %}</a>
</li>
</ul>
{% endif %}
<!-- Tab panes -->
<div class="tab-content">
<div class="tab-pane active" id="home_common">
<div class="tab-pane active" id="common">
{{ form_row(form.name) }}
{% if form.parent%}
{{ form_row(form.parent) }}
@ -83,6 +87,10 @@
</div>
{% block additional_panes %}{% endblock %}
<div class="tab-pane" id="attachments">
{% include "AdminPages/_attachments.html.twig" %}
</div>
</div>
{{ form_row(form.save) }}

View file

@ -0,0 +1,94 @@
{% set delete_btn %}
<button type="button" class="btn btn-danger lot_btn_delete" onclick="delete_attachment_entry(this);">
<i class="fas fa-trash-alt fa-fw"></i>
{% trans %}attachment.delete{% endtrans %}
</button>
{% endset %}
{#{{ form_row(form.master_picture_attachment) }} #}
<table class="table table-striped table-sm" id="attachments_table" data-prototype="{% if form.attachments.vars.prototype is defined %}{{ form_widget(form.attachments.vars.prototype)|e('html_attr') }}{% endif %}">
<tbody>
{% for attachment in form.attachments %}
<tr>
<td>
{{ form_widget(attachment) }}
</td>
<td>
{{ delete_btn }}
{% set attach = attachment.vars.value %}
{% if attachment_helper.fileExisting(attach) %}
{% if not attach.external %}
<br><br>
<h6>
<span class="badge badge-primary">
<i class="fas fa-fw fa-file"></i> {{ attach.filename }}
</span>
<br>
<span class="badge badge-secondary">
<i class="fas fa-hdd fa-fw"></i> {{ attachment_helper.humanFileSize(attach) }}
</span>
</h6>
{% else %}
<br><br>
<h6>
<span class="badge badge-primary">
<i class="fas fa-fw fa-globe"></i> {% trans %}attachment.external{% endtrans %}
</span>
</h6>
{% endif %}
{% else %}
<br><br>
<h6>
<span class="badge badge-warning">
<i class="fas fa-exclamation-circle fa-fw"></i> {% trans %}attachment.file_not_found{% endtrans %}
</span>
</h6>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
<button type="button" class="btn btn-success" onclick="create_attachment_entry(this)">
<i class="fas fa-plus-square fa-fw"></i>
{% trans %}attachment.create{% endtrans %}
</button>
<script>
function delete_attachment_entry(btn) {
window.bootbox.confirm('{% trans %}part_lot.edit.delete.confirm{% endtrans %}', function (result) {
if(result) {
$(btn).parents("tr").remove();
}
})
}
function create_attachment_entry(btn) {
//Determine the table, so we can determine, how many entries there are already.
$holder = $("#attachments_table");
var index = $holder.find(":input").length;
var newForm = $holder.data("prototype");
//Increase the index
newForm = newForm.replace(/__name__/g, index);
newForm = '<td>' + newForm + '</td>';
$newFormRow = $('<tr></tr>').html(newForm);
//Add delete button
$btn = '<td>' + '{{ delete_btn|e('js') }}' + '</td>';
$newFormRow.append($btn);
$holder.append($newFormRow);
//Reinit the selectpickers
$(".selectpicker").selectpicker();
$(".file").fileinput();
}
</script>