Upload files to a book from show book view.
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
// mydropzone_controller.js
|
// mydropzone_controller.js
|
||||||
|
|
||||||
import { Controller } from '@hotwired/stimulus';
|
import { Controller } from '@hotwired/stimulus';
|
||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
export default class extends Controller {
|
export default class extends Controller {
|
||||||
connect() {
|
connect() {
|
||||||
@@ -18,19 +19,27 @@ export default class extends Controller {
|
|||||||
|
|
||||||
_onConnect(event) {
|
_onConnect(event) {
|
||||||
// The dropzone was just created
|
// The dropzone was just created
|
||||||
console.info(event);
|
// console.info(event);
|
||||||
console.info('onconnect');
|
console.info('onconnect');
|
||||||
|
//
|
||||||
|
// axios.get('/book/search/modyfikowany+węgiel').then(response => {
|
||||||
|
// console.info(response.data);
|
||||||
|
// });
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_onChange(event) {
|
_onChange(event) {
|
||||||
// The dropzone just changed
|
// The dropzone just changed
|
||||||
console.info(event);
|
console.info(event);
|
||||||
console.info('onchange');
|
console.info('onchange');
|
||||||
|
|
||||||
|
event.target.closest('form').submit();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_onClear(event) {
|
_onClear(event) {
|
||||||
// The dropzone has just been cleared
|
// The dropzone has just been cleared
|
||||||
console.info(event);
|
// console.info(event);
|
||||||
console.info('onclear');
|
console.info('onclear');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,6 +5,7 @@ namespace App\Controller;
|
|||||||
use App\Entity\Book;
|
use App\Entity\Book;
|
||||||
use App\Entity\File;
|
use App\Entity\File;
|
||||||
use App\Form\BookType;
|
use App\Form\BookType;
|
||||||
|
use App\Form\FileType;
|
||||||
use App\Repository\BookRepository;
|
use App\Repository\BookRepository;
|
||||||
use App\Repository\FileRepository;
|
use App\Repository\FileRepository;
|
||||||
use App\Service\FileService;
|
use App\Service\FileService;
|
||||||
@@ -83,11 +84,33 @@ class BookController extends AbstractController
|
|||||||
return new JsonResponse($bookFinder->byUrl(base64_decode($urlInBase64)));
|
return new JsonResponse($bookFinder->byUrl(base64_decode($urlInBase64)));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[Route('/{id}', name: 'app_book_show', methods: ['GET'])]
|
#[Route('/{id}', name: 'app_book_show', methods: ['GET', 'POST'])]
|
||||||
public function show(Book $book): Response
|
public function show(Book $book, Request $request, FileRepository $fileRepository): Response
|
||||||
{
|
{
|
||||||
return $this->render('book/show.html.twig', [
|
$fileForm = $this->createForm(FileType::class);
|
||||||
|
$fileForm->handleRequest($request);
|
||||||
|
|
||||||
|
if ($fileForm->isSubmitted() && $fileForm->isValid()) {
|
||||||
|
/** @var \Symfony\Component\HttpFoundation\File\UploadedFile[] $ebooks */
|
||||||
|
$ebook = $request->files->get('file')['file'];
|
||||||
|
$file = new File();
|
||||||
|
$file->setFileName(trim($ebook->getClientOriginalName()));
|
||||||
|
$file->setFileSize($ebook->getSize());
|
||||||
|
$file->setExtension($ebook->guessClientExtension());
|
||||||
|
$file->setBook($book);
|
||||||
|
$fileRepository->add($file, true);
|
||||||
|
|
||||||
|
$ebook->move(
|
||||||
|
$this->getParameter('book_files'),
|
||||||
|
'ebook_' . $book->getId() . '_' .
|
||||||
|
md5($file->getFileName()) . '.' .
|
||||||
|
$file->getExtension()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->renderForm('book/show.html.twig', [
|
||||||
'book' => $book,
|
'book' => $book,
|
||||||
|
'file_form' => $fileForm
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,12 +165,15 @@ class BookController extends AbstractController
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[Route('/{id}', name: 'app_book_delete', methods: ['POST'])]
|
#[Route('/{id}', name: 'app_book_delete', methods: ['POST'])]
|
||||||
public function delete(Request $request, Book $book, BookRepository $bookRepository, FileService $fileService): Response
|
public function delete(
|
||||||
{
|
Request $request,
|
||||||
|
Book $book,
|
||||||
|
BookRepository $bookRepository,
|
||||||
|
FileService $fileService
|
||||||
|
): Response {
|
||||||
if ($this->isCsrfTokenValid('delete' . $book->getId(), $request->request->get('_token'))) {
|
if ($this->isCsrfTokenValid('delete' . $book->getId(), $request->request->get('_token'))) {
|
||||||
$fileService->removeFiles($book->getFiles());
|
$fileService->removeFiles($book->getFiles());
|
||||||
$bookRepository->remove($book, true);
|
$bookRepository->remove($book, true);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->redirectToRoute('app_book_index', [], Response::HTTP_SEE_OTHER);
|
return $this->redirectToRoute('app_book_index', [], Response::HTTP_SEE_OTHER);
|
||||||
|
|||||||
39
src/Form/FileType.php
Normal file
39
src/Form/FileType.php
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Form;
|
||||||
|
|
||||||
|
use App\Entity\File;
|
||||||
|
use Symfony\Component\Form\AbstractType;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||||
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
|
use Symfony\UX\Dropzone\Form\DropzoneType;
|
||||||
|
|
||||||
|
class FileType extends AbstractType
|
||||||
|
{
|
||||||
|
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||||
|
{
|
||||||
|
$builder
|
||||||
|
->add(
|
||||||
|
'file',
|
||||||
|
DropzoneType::class,
|
||||||
|
[
|
||||||
|
'mapped' => false,
|
||||||
|
'data_class' => null,
|
||||||
|
'required' => false,
|
||||||
|
'attr' => [
|
||||||
|
'data-controller' => 'mydropzone',
|
||||||
|
'accept' => ".pdf, .epub, .mobi",
|
||||||
|
'placeholder' => 'Drag and drop or browse'
|
||||||
|
]
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function configureOptions(OptionsResolver $resolver): void
|
||||||
|
{
|
||||||
|
$resolver->setDefaults([
|
||||||
|
'data_class' => File::class,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Description</th>
|
<th>Description</th>
|
||||||
<td>{{ book.description | nl2br }}</td>
|
<td>{{ book.description | nl2br }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Publisher</th>
|
<th>Publisher</th>
|
||||||
@@ -61,6 +61,10 @@
|
|||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</table>
|
</table>
|
||||||
|
{{ form_start(file_form) }}
|
||||||
|
{{ form_widget(file_form) }}
|
||||||
|
<button class="btn btn-primary">{{ button_label|default('Save') }}</button>
|
||||||
|
{{ form_end(file_form) }}
|
||||||
|
|
||||||
<a href="{{ path('app_book_index') }}">back to list</a>
|
<a href="{{ path('app_book_index') }}">back to list</a>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user