Size: a a a

2021 September 29

ПГ

Павел Г. in symfony
Это не в ЕА, это надо в формы
источник

ПГ

Павел Г. in symfony
Ну да, видимо надо кастом тайп. Там как раз будет form builder и уже можно навешивать трансформеры
источник

c

cyph3r in symfony
источник

ПГ

Павел Г. in symfony
Вот сами всё нашли :)
источник

c

cyph3r in symfony
А как его вызывать?
я вот так вот пробовал.
TextField::new('<field>')->setFormType(JsonType::class),
но меня обламывает textconfigurator так как значение не строка. до вызова jsontype не доходит даже.
источник

S

STEM in symfony
Проблемка нарисовалась. Я хочу сделать свой ArgumentResolver. Создал класс, указал ему тег controller.argument_value_resolver и большой приоритет. Указываю в контроллере в аргументе сущность и на меня ругается доктрина. Что с этим делать? Я хочу указывать какие-то объекты в аргументах методов контроллеров и чтобы они прогонялись сначала через мой ArgumentResolver и уже если ему не понравилось, то это все шло дальше
источник

AB

Andrey Bakharev in symfony
здрасьте, вопрос от СЗЗБ по доктрине
старый проект (симфони 3.4, доктрина 2.5.14), есть ентити, где много чего понавешано
допустим, кастомер, у которого может быть скидка на отдельные товары:
class Customer {
 /**
  * @ORM\OneToMany(targetEntity="\ProductDiscount", mappedBy="customer", cascade={"persist"}, orphanRemoval=true)
  */
 private $productDiscounts;
 public function getProductDiscount(Product $product) {
   $criteria = ...
   $discount = $this->productDiscounts->matching($criteria)->first();
   return $discount->percent();
 }
}
для отдельных товаров работает, но если запрашивать скидку для группы товаров, то из-за matching не вся коллекция запрашивается, а только часть
т.е. для n товаров будет N запросов, естесно все тормозит
можно легко пофиксить добавив $this->discounts вначале, но об этом легко забыть, да и мест таких дофига (не только товары, но и сервисы и прочее), хотелось бы подчистить

придумал создать класс со скидками, где каждая скидка в отдельном классе, т.е.
class ProductDiscounts {
 /**
  * @ORM\OneToMany(targetEntity="ProductDiscount", mappedBy="discounts", cascade={"persist"}, orphanRemoval=true)
  */
 private $productDiscounts;
 public function getDiscount(Product $product) {
   $criteria = ...
   $discount = $this->productDiscounts->matching($criteria)->first();
   return $discount->percent();
 }
}
class Discounts {
 /**
    * @ORM\OneToOne(targetEntity="ProductDiscounts")
    * @ORM\JoinColumn(name="id", referencedColumnName="id")
  */
 private $productDiscounts;
 ...
 public function products() {
   return $this->productDiscounts;
 }
 ...
}
class Customer {
 /**
    * @ORM\OneToOne(targetEntity="ProductDiscounts")
    * @ORM\JoinColumn(name="id", referencedColumnName="id")
  */
 private $discounts;
 public function getProductDiscount(Product $product) {
   return $this->discounts->products->getDiscount(product)->percent();
 }
}
для Discounts и ProductDiscounts мне отдельные таблички не нужны - достаточно существущей кастомера, т.е. те классы я замапил на существующую табичку
все работает, но со скидками можно работать только после того, как запросишь кастомера/скидки с базы:
$customer = $em->find(Customer::class, $customerId);
$customer->discounts()->products()->setDiscount($product, '12.3');
$em->flush();
// или
$discounts = $em->find(Discounts::class, $customerId);
$discounts->products()->setDiscount($product, '12.3');
$em->flush();
а вот если со скидками работать сразу после создания объекта - вылетает ошибка
т.е. следующее не работает:
$customer = new Customer();
$customer->discounts()->products()->setDiscount($product, '12.3');
$em->flush();
пробовал разное, и ошибки разные: нет персиста, или существующий id уже есть и т.д.

на данный момент таких мест с ошибкой нет, но они легко могут появиться
и как здесь быть, чтобы работало всегда, а не только после загрузки кастомера?

можно, конечно, для всего сделать отдельные таблички и там все автоматом будет персиститься/сохраняться, но там, по хорошему, будет только одно поле: customerId, не нравится мне такой оверхед, хотелось бы на одной все разрулить, но какие варианты для этого есть?
ну или по доктрине мож кто канал посоветует
источник

ПГ

Павел Г. in symfony
Поидее верно, надо дебажить... Поидее в форме должно все настраиваться, что куда и как мапится. А Еа обычная надстройка
источник

AB

Andrey Bakharev in symfony
что-то типа такого интересует: https://www.doctrine-project.org/projects/doctrine-orm/en/current/cookbook/decorator-pattern.html#persisting-the-decorator-pattern
только чтобы декоратор именно как декоратор был, а не как наследник, которого в базе отдельно храним
источник

c

cyph3r in symfony
пришлось еще и класс филда отдельный создавать чтоб другие конфигураторы не вмешивались
источник

ПГ

Павел Г. in symfony
Странно что до такого дошло. Кейс вроде array to string, должен покрываться без такого
источник

VS

Valery Smirnoff in symfony
Всем привет! Переношу проект на symfony в связке с codeception. Подскажите как работать с сервис контейнером в тестах codeception. В рамках одного теста достал сервис контейнер и заменил в нем зависимсоть. Правда пришлось использовать persistService иначе контейнер выкидывает мой замоканный класс при старте прила в тесте. В следующем тесте(в рамках того же тест класса) замокать класс уже не получается, так как сервис контейнер не дает заменить ранее замоканный класс и выкидывает ошибку вида ...service is already initialized, you cannot replace it. Есть метод unpersistService, который я сходу попробовал и он не сработал, а в детали его реализауии пока не вникал. Подскажите проблема в подходе? или же что-то необходимо доконфигурировать?
источник

SM

Sergey Milegov in symfony
Не меняй сервисы в контейнере
источник

OK

Oleg Krasavin in symfony
Зачем мокать сервисы в функциональных тестах? Это дичь.
источник

OK

Oleg Krasavin in symfony
Определите интерфейс, напишите имплементацию для тестов(InMemory/DummyBlahBlah) и подсовывайте в тест-среде в контейнер как обычный сервис.

И уже на основе этих тест-имплементаций делайте нужные ассерты
источник

VS

Valery Smirnoff in symfony
Каким образом подсовывать?
источник

OK

Oleg Krasavin in symfony
переопределяя класс в services_test.yaml
источник

OK

Oleg Krasavin in symfony
или .php смотря в чем конфиги у вас
источник

VS

Valery Smirnoff in symfony
А каким образом через такой поход мокать разные результаты использования замоканого класса?
источник

OK

Oleg Krasavin in symfony
Вот как пример

final class InMemoryResolver implements PaymentResolverInterface
{
   private array $queue;

   public function resolve(ImportedPayment $payment): ResolveResult
   {
       return array_shift($this->queue);
   }

   public function resolveWith(ResolveResult $resolveResult): void
   {
       $this->queue[] = $resolveResult;
   }
}
источник