У меня есть следующая задача: запретить создавать новое сообщение больше за 1 минуту. Итак, логика следующая. Когда пользователь отправляет форму, cookie создается с продолжительностью жизни 60 секунд. Затем, когда пользователь попытается отправить снова, я проверяю, существует ли файл cookie. Если true - перенаправление пользователя на главную страницу. Если false - создайте сообщение, перейдите в базу данных, creat cookie. Поэтому я создаю следующее действие в своем контроллере:
namespace Faster\Bundle\MessageBundle\Controller;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Cookie;
use Faster\Bundle\MessageBundle\Entity\Message;
use Faster\Bundle\MessageBundle\Form\MessageType;
class MessageController extends Controller
{
...
public function createAction(Request $request)
{
$message = new Message();
$form = $this->createCreateForm($message);
$form->handleRequest($request);
if ($form->isValid()) {
$valueOfCookiePerMinute = $request->cookies->get('perMinute');
if ($valueOfCookieName) {
return $this->redirect($this->generateUrl('message'));
}
else {
$cookie = new Cookie('perMinute', 'CookieIsAlreadyExist', time() + 60);
$response = new RedirectResponse($this->generateUrl('message'));
$response->headers->setCookie($cookie);
$em = $this->getDoctrine()->getManager();
$em->persist($message);
$em->flush();
return $response;
}
}
...
}
Но я думаю, что это регулятор жира. Я думаю, что это может быть служба для этой части кода:
$valueOfCookiePerMinute = $request->cookies->get('perMinute');
if ($valueOfCookieName) {
return $this->redirect($this->generateUrl('message'));
}
else {
$cookie = new Cookie('perMinute', 'CookieIsAlreadyExist', time() + 60);
$response = new RedirectResponse($this->generateUrl('message'));
$response->headers->setCookie($cookie);
$em = $this->getDoctrine()->getManager();
$em->persist($message);
$em->flush();
return $response;
}
Но для меня сложно использовать такую услугу. Я не могу понять, как я могу это сделать/Пожалуйста, помогите мне реализовать и понять. Спасибо.
Вы правы, ваш контроллер должен быть фасадом, поэтому рекомендуется установить этот код в службе.
Сначала создайте класс:
// Messaging/MessageTimer.php
namespace Faster\Bundle\MessageBundle\Messaging;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\Routing\RouterInterface;
use Doctrine\Common\Persistence\ManagerRegistry;
class MessageTimer implements MessageTimerInterface
{
/**
* The database object manager.
*
* @var Doctrine\Common\Persistence\ObjectManager
*/
private $objectManager;
/**
* The router.
*
* @var RouterInterface
*/
private $router;
/**
* Constructor.
*
* @param ManagerRegistry $managerRegistry The manager registry.
*/
public function __construct(
ManagerRegistry $managerRegistry,
RouterInterface $router
)
{
$this->objectManager = $managerRegistry->getManager();
$this->router = $router;
}
/**
* {@inheritdoc}
*/
public function processRequest(Request $request)
{
$valueOfCookiePerMinute = $request->cookies->get('perMinute');
if ($valueOfCookieName) {
return new RedirectResponse($this->router->generate('message'));
} else {
$cookie = new Cookie('perMinute', 'CookieIsAlreadyExist', time() + 60);
$response = new RedirectResponse($this->router->generate('message'));
$response->headers->setCookie($cookie);
$this->objectManager->persist($message);
$this->objectManager->flush();
return $response;
}
}
}
Как вы можете видеть, мы используем интерфейс для использования низкого сочетания (вы сможете легко заменить внедрение этого класса и, следовательно, службы). Это необходимо для использования инъекции зависимостей в полном объеме!
// Messaging/MessageTimerInterface.php
namespace Faster\Bundle\MessageBundle\Messaging;
use Symfony\Component\HttpFoundation\Request;
interface MessageTimerInterface
{
/**
* Process a request.
*
* @param Request $request The request.
*/
public function processRequest(Request $request);
}
Затем вы должны объявить услугу в этом классе:
# Resources/config/services.yml
parameters:
your_own.message_timer.class: Faster\Bundle\MessageBundle\Messaging\MessageTimer
services:
your_own.message_timer:
class: %your_own.message_timer.class%
arguments: [@doctrine, @router]
Наконец, вы должны использовать его только в своем контроллере:
namespace Faster\Bundle\MessageBundle\Controller;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Cookie;
use Faster\Bundle\MessageBundle\Entity\Message;
use Faster\Bundle\MessageBundle\Form\MessageType;
class MessageController extends Controller
{
// ...
public function createAction(Request $request)
{
$message = new Message();
$form = $this->createCreateForm($message);
$form->handleRequest($request);
if ($form->isValid()) {
return $this->get('your_own.message_timer').processRequest($request);
}
// ...
}
Attempted to call method "generateUrl" on class "Faster\Bundle\MessageBundle\Messaging\MessageTimer".
Можете ли вы помочь проверить это?