<?php
|
declare(strict_types=1);
|
|
namespace App\Controller;
|
|
use App\Entity\Book;
|
use App\Entity\OustedBook;
|
use App\Form\BulkOustType;
|
use App\Form\OustType;
|
use App\Repository\BookRepository;
|
use App\Repository\OustedBookRepository;
|
use App\Service\Library;
|
use Knp\Component\Pager\PaginatorInterface;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\Routing\Attribute\Route;
|
use Symfony\Component\Routing\Requirement\Requirement;
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
|
class OustedBookController extends AbstractController {
|
#[Route('/ousted', name: 'ousted_list', methods: ['GET'])]
|
public function list(Request $request, OustedBookRepository $books, PaginatorInterface $paginator): Response {
|
return $this->render('ousted/list.html.twig', [
|
'pagination' => $paginator->paginate(
|
$books->createListQueryBuilder(),
|
max(1, $request->query->getInt('page', 1)),
|
),
|
]);
|
}
|
|
#[Route('/ousted/{id}', name: 'ousted_show', requirements: ['id' => Requirement::DIGITS], methods: ['GET'])]
|
public function show(OustedBook $book): Response {
|
return $this->render('ousted/show.html.twig', ['book' => $book]);
|
}
|
|
#[Route('/book/{id}/oust', name: 'book_oust', requirements: ['id' => Requirement::DIGITS], methods: ['POST'])]
|
public function oust(Request $request, Book $book, Library $library): Response {
|
$form = $this->createForm(OustType::class);
|
$form->handleRequest($request);
|
|
if ($book->isBorrowed() || !$form->isSubmitted() || !$form->isValid()) {
|
$this->addFlash('error', 'action_rejected');
|
|
return $this->redirectToRoute('book_show', ['id' => $book->getId()]);
|
}
|
|
$ousted = $library->oust($book, $form->getData()['reason']);
|
$this->addFlash('success', 'ousted_done');
|
|
return $this->redirectToRoute('ousted_show', ['id' => $ousted->getId()]);
|
}
|
|
/**
|
* Ousts the books that an inventory did not find: those not seen on or after a date.
|
*/
|
#[Route('/ousted/bulk', name: 'ousted_bulk', methods: ['GET', 'POST'])]
|
public function bulk(Request $request, BookRepository $books, Library $library, PaginatorInterface $paginator, TranslatorInterface $translator): Response {
|
if ($request->isMethod('POST')) {
|
$form = $this->createForm(BulkOustType::class, null, ['confirm' => true]);
|
$form->handleRequest($request);
|
|
if (!$form->isSubmitted() || !$form->isValid()) {
|
$this->addFlash('error', 'action_rejected');
|
|
return $this->redirectToRoute('ousted_bulk');
|
}
|
|
['notSeenSince' => $since, 'reason' => $reason, 'selection' => $selection] = $form->getData();
|
$back = ['bulk_oust' => ['notSeenSince' => $since->format('Y-m-d'), 'reason' => $reason]];
|
|
if (!hash_equals($books->notSeenSinceFingerprint($since), (string)$selection)) {
|
$this->addFlash('error', 'bulk_oust_changed');
|
|
return $this->redirectToRoute('ousted_bulk', $back);
|
}
|
|
$ousted = $library->oustAll($books->createNotSeenSinceQueryBuilder($since)->getQuery()->getResult(), $reason);
|
$this->addFlash('success', $translator->trans('bulk_oust_done', ['%count%' => $ousted]));
|
|
return $this->redirectToRoute('ousted_list');
|
}
|
|
$form = $this->createForm(BulkOustType::class);
|
$form->handleRequest($request);
|
$parameters = ['form' => $form, 'pagination' => null];
|
|
if ($form->isSubmitted() && $form->isValid()) {
|
['notSeenSince' => $since, 'reason' => $reason] = $form->getData();
|
|
$parameters['since'] = $since;
|
$parameters['borrowed'] = $books->countNotSeenSince($since, borrowed: true);
|
$parameters['pagination'] = $paginator->paginate(
|
$books->createNotSeenSinceQueryBuilder($since),
|
max(1, $request->query->getInt('page', 1)),
|
);
|
$parameters['confirm_form'] = $this->createForm(BulkOustType::class, [
|
'notSeenSince' => $since,
|
'reason' => $reason,
|
'selection' => $books->notSeenSinceFingerprint($since),
|
], ['confirm' => true, 'action' => $this->generateUrl('ousted_bulk')]);
|
}
|
|
return $this->render('ousted/bulk.html.twig', $parameters);
|
}
|
|
#[Route('/ousted/{id}/restore', name: 'ousted_restore', requirements: ['id' => Requirement::DIGITS], methods: ['POST'])]
|
public function restore(Request $request, OustedBook $book, Library $library): Response {
|
if (!$this->isCsrfTokenValid('restore' . $book->getId(), $request->getPayload()->getString('_token'))) {
|
$this->addFlash('error', 'action_rejected');
|
|
return $this->redirectToRoute('ousted_show', ['id' => $book->getId()]);
|
}
|
|
$restored = $library->restore($book);
|
$this->addFlash('success', 'ousted_restored');
|
|
return $this->redirectToRoute('book_show', ['id' => $restored->getId()]);
|
}
|
}
|