Symfony2. Создать сервис для установки файлов cookie и перенаправления

0

У меня есть следующая задача: запретить создавать новое сообщение больше за 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;
            }

Но для меня сложно использовать такую услугу. Я не могу понять, как я могу это сделать/Пожалуйста, помогите мне реализовать и понять. Спасибо.

Теги:
cookies

1 ответ

1

Вы правы, ваш контроллер должен быть фасадом, поэтому рекомендуется установить этот код в службе.

Сначала создайте класс:

// 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);
        }

    // ...
}
  • 0
    Здравствуй! Я использую ваш код и получаю сообщение об ошибке: Attempted to call method "generateUrl" on class "Faster\Bundle\MessageBundle\Messaging\MessageTimer". Можете ли вы помочь проверить это?
  • 0
    О да, мой плохой! Я исправляю это сейчас.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню