Allow to move a attachment to secure location (and back).

This commit is contained in:
Jan Böhmer 2019-10-19 19:30:16 +02:00
parent 9385d28e40
commit 63dc22f524
2 changed files with 70 additions and 8 deletions

View file

@ -44,6 +44,8 @@ use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\UrlType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Routing\RouterInterface;
@ -83,6 +85,13 @@ class AttachmentFormType extends AbstractType
'attr' => ['class' => 'form-control-sm'],
'label_attr' => ['class' => 'checkbox-custom']]);
$builder->add('secureFile', CheckboxType::class, ['required' => false,
'label' => $this->trans->trans('attachment.edit.secure_file'),
'mapped' => false,
'attr' => ['class' => 'form-control-sm'],
'help' => $this->trans->trans('attachment.edit.secure_file.help'),
'label_attr' => ['class' => 'checkbox-custom']]);
$builder->add('url', TextType::class, [
'label' => $this->trans->trans('attachment.edit.url'),
'required' => false,
@ -104,11 +113,6 @@ class AttachmentFormType extends AbstractType
'attr' => ['class' => 'form-control-sm'],
'label_attr' => ['class' => 'checkbox-custom']]);
$builder->add('secureFile', CheckboxType::class, ['required' => false,
'label' => $this->trans->trans('attachment.edit.secure_file'),
'mapped' => false,
'attr' => ['class' => 'form-control-sm'],
'label_attr' => ['class' => 'checkbox-custom']]);
$builder->add('file', FileType::class, [
'label' => $this->trans->trans('attachment.edit.file'),
@ -120,8 +124,18 @@ class AttachmentFormType extends AbstractType
'maxSize' => $options['max_file_size']
])
]
]);
//Check the secure file checkbox, if file is in securefile location
$builder->get('secureFile')->addEventListener(
FormEvents::PRE_SET_DATA,
function (FormEvent $event) {
$attachment = $event->getForm()->getParent()->getData();
if ($attachment instanceof Attachment) {
$event->setData($attachment->isSecure());
}
}
);
}
public function configureOptions(OptionsResolver $resolver)

View file

@ -72,7 +72,7 @@ class AttachmentSubmitHandler
protected $httpClient;
protected $mimeTypes;
public function __construct(AttachmentPathResolver $pathResolver, bool $allow_attachments_downloads,
public function __construct (AttachmentPathResolver $pathResolver, bool $allow_attachments_downloads,
HttpClientInterface $httpClient, MimeTypesInterface $mimeTypes)
{
$this->pathResolver = $pathResolver;
@ -179,6 +179,9 @@ class AttachmentSubmitHandler
$this->downloadURL($attachment, $options);
}
//Move the attachment files to secure location (and back) if needed
$this->moveFile($attachment, $options['secure_attachment']);
//Check if we should assign this attachment to master picture
//this is only possible if the attachment is new (not yet persisted to DB)
if ($options['become_preview_if_empty'] && $attachment->getID() === null && $attachment->isPicture()) {
@ -191,12 +194,57 @@ class AttachmentSubmitHandler
return $attachment;
}
/**
* Move the given attachment to secure location (or back to public folder) if needed.
* @param Attachment $attachment The attachment for which the file should be moved.
* @param bool $secure_location This value determines, if the attachment is moved to the secure or public folder.
* @return Attachment The attachment with the updated filepath
*/
protected function moveFile(Attachment $attachment, bool $secure_location) : Attachment
{
//We can not do anything on builtins or external ressources
if ($attachment->isBuiltIn() || $attachment->isExternal()) {
return $attachment;
}
//Check if we need to move the file
if ($secure_location === $attachment->isSecure()) {
return $attachment;
}
//Determine the old filepath
$old_path = $this->pathResolver->placeholderToRealPath($attachment->getPath());
if (!file_exists($old_path)) {
return $attachment;
}
$filename = basename($old_path);
//If the basename is not one of the new unique on, we have to save the old filename
if (!preg_match('/\w+-\w{13}\./', $filename)) {
//Save filename to attachment field
$attachment->setFilename($attachment->getFilename());
}
$ext = pathinfo($filename, PATHINFO_EXTENSION);
$new_path = $this->generateAttachmentPath($attachment, $secure_location)
. DIRECTORY_SEPARATOR . $this->generateAttachmentFilename($attachment, $ext);
//Move file to new directory
$fs = new Filesystem();
$fs->rename($old_path, $new_path);
//Save info to attachment entity
$new_path = $this->pathResolver->realPathToPlaceholder($new_path);
$attachment->setPath($new_path);
return $attachment;
}
/**
* Download the URL set in the attachment and save it on the server
* @param Attachment $attachment
* @param array $options The options from the handleFormSubmit function
* @return Attachment The attachment with the new filepath
* @throws AttachmentDownloadException
*/
protected function downloadURL(Attachment $attachment, array $options) : Attachment
{