diff --git a/src/Form/AttachmentFormType.php b/src/Form/AttachmentFormType.php index 990f7959..ac30bdfb 100644 --- a/src/Form/AttachmentFormType.php +++ b/src/Form/AttachmentFormType.php @@ -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) diff --git a/src/Services/Attachments/AttachmentSubmitHandler.php b/src/Services/Attachments/AttachmentSubmitHandler.php index 734818ae..2e6c9df0 100644 --- a/src/Services/Attachments/AttachmentSubmitHandler.php +++ b/src/Services/Attachments/AttachmentSubmitHandler.php @@ -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 {