• Symfony 4 - Doctrine - Repository как вытащить правельный тип данных??

    DevMan
    @DevMan
    по дефолту пдо получает числа как строки, и это при должном желании элементарно лечится.

    рецепт для пдо - Можно ли при запросе из БД получить цифру?
    рецепт конкретно для доктрины - https://coderwall.com/p/goyc8w/how-to-stop-doctrin...
    Ответ написан
    5 комментариев
  • Как создать каскадную форму Symfony 2?

    prototype_denis
    @prototype_denis
    Symfony
    Всё намного проще и само собой подходов куча.

    Классический подход НЕ подразумевает js и добавляет новые поля после каждого сабмита формы, решается крайне просто:

    <?php
    
    interface ObjectInterface {
        public function getCountry(): ?Country;
        public function getRegion(): ?Region;
    }
    
    class AppType
    {
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $builder
                ->add('country', EntityType::class, [
                    'class' => \App\Entity\Country::class,
                ])
            ;
    
            $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
                /** @var ObjectInterface $object */
                if (null === $object = $event->getData()) {
                    return;
                }
                $form = $event->getForm();
    
                if ($object->getCountry()) {
                    $form->add('region', EntityType::class, [
                        'class' => \App\Entity\Region::class,
                        'query_builder' => function (EntityRepository $repository) use ($object) {
                            return $repository->createQueryBuilder('e')->where('e.country = :country')->setParameter('country', $object->getCountry());
                        }
                    ]);
                }
    
                if ($object->getRegion()) {
                    $form->add('city', EntityType::class, [
                        'class' => \App\Entity\City::class,
                        'query_builder' => function (EntityRepository $repository) use ($object) {
                            return $repository->createQueryBuilder('e')->where('e.region = :region')->setParameter('region', $object->getRegion());
                        }
                    ]);
                }
            });
        }
    }


    Цена вопроса 3 POST запроса

    Но такой подход не удобен и только путает.

    Как решить?

    Одним из способов будет являться следующее:

    - Создаём контроллер с методами получения регионов, городов.
    - На фронте любыми способами рисуем инпут
    - Динамически (на фронте) делаем с этими формами что угодно
    - Отправляем форму

    В этом случае symfony форма будет выглядить примитивно

    $builder->add('country')->add('region')->add('city');


    Надо будет только задать группу валидации, где вы спокойненько провалидуриете всё дерево, начиная со страны.
    Цена вопроса - 2 ajax запроса, 1 POST

    Или...

    Рисуем форму
    $builder->add('country')->add('region')->add('city');

    Где region и city - ChoiceType пустые.
    Аяксом забираем с сервера регионы, а затем города.
    В событии формы (SUBMIT и POST_SUBMIT с приоритетом нижк валидатора) ручками ссетим эти данные.

    Лично мне предпочтителен первый подход (классика без js), на которую потом уже навешиваются плюшки.
    Запросов больше, но объект собирается, как на фронте, так и на бэке последовательно и нет никаких проблем ни с редактированием, ни с созданием.

    Для понимания. PRE_SET_DATA - это GET запрос, прим перед резолвом данных (имеено по этому в коде проверка на null). PRE_SUBMIT - это POST запрос. В обоих случаях у вас объект в событии.
    Соответственно за последовательность отвечает data_class, объект DTO (или сущнсоть) в котором будет страна, регион и город.
    Бонусом (разобравшись с этой ересью) - валидаторы, всякие ресты и сериализаторы прикручиваются к таким формам на раз-два по необходимости.

    > Пробовал - не работает. В него не попадают значения динамических полей

    Отвечу на ваш коммент тут.

    Во-первых - событие PRE_SET_DATA с проверкой данных на null
    Во-вторых - событие PRE_SUBMIT (пожеланию) на биндинг данных (если у вас в форме не используется сущности)

    symfony.com/doc/current/form/dynamic_form_modifica...
    Ответ написан
    1 комментарий
  • Как вставить строки в таблицу order?

    prototype_denis
    @prototype_denis
    Symfony
    Зарезервированные слова необходимо брать в кавычки

    /**
     * @ORM\Table(name="`order`")
     */
    class Order {}
    Ответ написан
    2 комментария
  • Постоянно запущенный скрипт на PHP, как реализовать?

    @Wexter
    серверы очередей gearman/rabbitmq/...
    Ответ написан
    Комментировать
  • Валидация Request $request?

    BoShurik
    @BoShurik Куратор тега Symfony
    Symfony developer
    Дополню voronkovich

    https://symfony.com/doc/current/controller/argumen...

    class NewUserRequestResolver implements \Symfony\Component\HttpKernel\Controller\ArgumentValueResolverInterface
    {
        /**
         * @var \Symfony\Component\Serializer\SerializerInterface
         */
        private $serializer;
    
        /**
         * @var \Symfony\Component\Validator\Validator\ValidatorInterface
         */
        private $validator;
    
        public function __construct(
            \Symfony\Component\Serializer\SerializerInterface $serializer,
            \Symfony\Component\Validator\Validator\ValidatorInterface $validator
        ) {
            $this->serializer = $serializer;
            $this->validator = $validator;
    
        }
    
        /**
         * @inheritDoc
         */
        public function supports(\Symfony\Component\HttpFoundation\Request $request, \Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata $argument)
        {
            return NewUserRequest::class === $argument->getType();
        }
    
        /**
         * @inheritDoc
         */
        public function resolve(\Symfony\Component\HttpFoundation\Request $request, \Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata $argument)
        {
            $newUserRequest = $this->serializer->deserialize($request->getContent(), NewUserRequest::class,'json');
            $constraints = $this->validator->validate($newUserRequest);
            if ($constraints->count() == 0) {
                yield $newUserRequest;
            }
    
            throw new \Symfony\Component\HttpKernel\Exception\BadRequestHttpException();
        }
    }


    В итоге в контроллере можно будет использовать
    public function registerNewUser(CreqteNewUserRequest $request)
    Ответ написан
    9 комментариев
  • Как выпилить компоненты (doctrine, twig) из symfony?

    BoShurik
    @BoShurik Куратор тега Symfony
    Symfony developer
    Отказаться от использования "symfony/symfony" и подключать конкретные компоненты, которые необходимы

    Рекомендую посмотреть в сторону Symfony Flex, он как раз создан для решения этой проблемы
    Ответ написан
    Комментировать
  • Книга о том как правильно должен работать программист?

    Astrohas
    @Astrohas
    Python/Django Developer
    "Как заставить себя не спать"
    "Зрение человека"
    "Легкие фитнес упражнения для беременных и полных"
    ----
    вот те книги что нужны программисту
    Ответ написан
    2 комментария
  • Какой тип маршрутизации в Symfony лучше использовать?

    skobkin
    @skobkin
    Гентушник, разработчик на PHP и Symfony.
    Я предпочитаю YAML.
    В сущностях довольно удобно держать аннотации, т.к. при правильном подходе работа идёт от объектов, а не от таблиц. Это редко может помешать.
    В случае с контроллерами же вполне может быть необходимость сходу понять "а куда мы придём в нашем приложении, если пойдём по такому-то адресу". И когда маршруты разбросаны по куче контроллеров, это сделать довольно затруднительно. Хорошо это работает только в обратную сторону: "а какой у нас адрес для этого экшена".
    Так вот в случае использования YAML и плагина для IDE, который позволяет в один клик скакнуть от кода экшена к описанию маршрута или наоборот, YAML позволяет быстро отвечать и на первый и на второй вопрос.

    Кроме того рекомендую ознакомиться с Symfony Best Practices, чтобы много вопросов "а как лучше" отпало. И да, как вы сможете заметить читая их, мой выбор YAML расходится с предложенной практикой. Но аргументацию см. выше.
    Ответ написан
    4 комментария
  • Есть ли способ при построении формы через FormBuilder указать какой виджет будет использоваться для рендеринга поля?

    @shoomyst
    dumb
    А какой виджет нужен? Насколько я помню, choice может быть либо селектом, либо группой радио-кнопок.
    Смотреть надо куда-то в сторону опций multiple и expanded
    Ответ написан
    8 комментариев