Max
нормально для тестов и прода менять значени ENV?)
Konstantin
да вполне
Max
Ох, пошел доказывать...
Alexander
Пробую создать АПИ. Везде отдаю JsonResponse... Но вот "отдать" ошибку (500,404) в Json. Не могу сообразить как. Подскажите где почитать? гугл выдает https://symfony.com/doc/current/controller/error_pages.html .но там уже речь о переопределении.. А мне пока бы просто переключиться на "не HTML" формат.
Vlad
у роутов переключить формат
Alexander
Это в конфигах искать?
Vlad
+
Alexander
ок. спасибо за наводку - пошел в этом направлении копать
Alexander
у роутов переключить формат
Если я правильно понял, указать в роутах формат, это решает проблему 500 ошибки., но 404 все равно отдает html
Ivan
Самый простой вариант подписаться на событие exception и отдать в нужном тебе формате. Ошибки кидать через Exception с нужными кодами и описаниями.
Ivan
Примерно так https://pastebin.com/dXTh9L3S
Alexander
Самый простой вариант подписаться на событие exception и отдать в нужном тебе формате. Ошибки кидать через Exception с нужными кодами и описаниями.
Спасибо.. я как раз читал про kernel.exception но уперся в отсутствие класса (который был в оппавшихся примерах GetResponseForExceptionEvent)
Alexander
Отлично.. с Subscriber все заработало как надо :)
Kirill
Всем привет! Подскажите, какими инструментами вы пользуетесь для логирования изменений в сущностях? У себя в проекте используем Gedmo\Loggable, но есть проблема: он не умеет логировать изменения многие-ко-многим. Если я у новости меняю теги, это нигде не сохраняется. Подскажите, пожалуйста, как этого можно добиться?
Юра
связь
Значит не обновил овнинг сайд
Юра
Там есть методы получения изменений в коллекции
Юра
Далее можно например использовать VarDumper чтобы показать это изменение
Юра
Я так делал
Юра
Прийдется малеха руками пописать код
Юра
Т.е. у тебя есть класс метадата из которого можно достать инфу про ассоциации и uof мз которого можно достать изменения и вардампер который может это сдампиьь в удобном виде
Юра
Осталось смешать и посолить
Kirill
Это да, я просто думал, что можно как-то автоматически это сделать.
Kirill
Спасибо!
Юра
Там кода получится строк 50
Юра
Я не встречал готового
Юра
Посерчи может есть бандл
Kirill
Я же правильно понимаю, что мне нужно в листенере отслеживать изменения и логировать вручную?
Юра
Йеп
Kirill
А нельзя ли как-то один листенер написать и чтобы он логировал изменения во всех сущностях?
Юра
Перед флашем например
Юра
Я же не зря написал про класс метадата
Kirill
в unitOfWork можно как-то определить, что коллекция manyToMany изменилась? Мне ведь только эти изменения нужно логировать, остальные логируются GedmoLoggable
Kirill
или придется вручную прописать у какой сущности какую связь отслеживать?
Юра
$metadata = $em->getMetadataFactory()->getMetadataFor(get_class($this->resourceItem)); $uw = $em->getUnitOfWork(); $uw->recomputeSingleEntityChangeSet($metadata, $this->resourceItem); $changeSet = $uw->getEntityChangeSet($this->resourceItem); $oldValues = []; $newValues = []; $insertDiff = []; $deleteDiff = []; $scheduledDeletions = $uw->getScheduledCollectionDeletions(); foreach ($metadata->getAssociationNames() as $associationName) { if ($metadata->isCollectionValuedAssociation($associationName)) { $propAccessor = $this->container->get('property_accessor'); /** @var PersistentCollection $collection */ $collection = $propAccessor->getValue($this->resourceItem, $associationName); if ($collection->isDirty() && $collection->getInsertDiff()) { $insertDiff[$associationName] = $collection->getInsertDiff(); } if ($collection->count() === 0) { foreach ($scheduledDeletions as $deletion) { if ($deletion === $collection) { $deleteDiff[$associationName] = 'Deleted completely'; } } } else { if ($collection->isDirty()) { $deleteDiff[$associationName] = $collection->getDeleteDiff(); } } } } foreach ($changeSet as $fieldName => $changes) { // handle datetime if ($changes[0] instanceof \DateTime && $changes[1] instanceof \DateTime) { if ($changes[0]->getTimestamp() === $changes[1]->getTimestamp()) { continue; } } $oldValues[$fieldName] = $changes[0]; $newValues[$fieldName] = $changes[1]; }
Юра
это кусок из моего кода
Юра
глянь может тебе поможет
Юра
не факт что там нет багов ) так что ничего не гарантирую
Юра
Например возможно это приведет к выгрузке всей коллекции. А может и нет. Хз
Юра
По идее там нет получения элементов не должно
Kirill
Спасибо!
Vlad
Если я правильно понял, указать в роутах формат, это решает проблему 500 ошибки., но 404 все равно отдает html
ну тут тебе надо как то по дефолту подснуть формат запроса, либо же лиснере или просто переопределить конфигурацию еророр рендера
Vlad
$services ->set('error_handler.error_renderer.serializer', SerializerErrorRenderer::class) ->args([ service('serializer'), 'json', service('error_renderer.html'), inline_service() ->factory([HtmlErrorRenderer::class, 'isDebug']) ->args([service('request_stack'), param('kernel.debug')]), ]) ;
Kirill
Как правильно подключить Listener, чтобы она отслеживал изменения во всех сущностях, а не в какой-то конкретной?
Kirill
кажется, просто не указывать entity)
Kirill
Помогите) Пишу обработчик preUpdate или onFlush, в них можно вызвать $uow->getScheduledCollectionUpdates() и получить коллекции many_to_many, которые будут обновлены. Проблема в том, что getScheduledCollectionUpdates всегда возвращает массив значений, даже если значения такие же, как были до этого. То есть мне нужно сравнить getScheduledCollectionUpdates с коллекцией, которая сейчас хранится в БД, но если я тут же получу нужную коллекцию у entity (в моем случае tags), то там уже проставлены новые значения. Как мне в обработчике получить актуальную коллекцию?
Иван
нельзя полагаться на магию доктрины
Иван
надо организовать код по обработчикам так, чтобы юзкейс проходил по фиксированному сценарию и тогда сначала есть старые значения, а потом новые и не надо ловить изменения в событиях компонента
Kirill
Мне нужно логировать изменения связей many_to_many. Gedmo\Loggable так не умеет. Решил написать листенер, один для всех сущностей, который будет логировать.
Nikolay
нельзя полагаться на магию доктрины
Я много огреб, когда такой чужой код дебажил
Иван
максимум, что я доверю доктрине - это заполнять updatedAt
Иван
Ничего)
тоже хороший вариант
Nikolay
На одном проекте с помощью магии организовано хранение истории изменений
Иван
Мне нужно логировать изменения связей many_to_many. Gedmo\Loggable так не умеет. Решил написать листенер, один для всех сущностей, который будет логировать.
боюсь в терминологии ДДД нет такой задачи логгировать надо изменения бизнессущностей, а не произвольные many_to_many связи
Kirill
Так менеджеру и скажу
Konstantin
Так менеджеру и скажу
а какая бизнес-задача-то?
Konstantin
вести аудит какой-то?
Kirill
Да, у нас GedmoLoggable логирует все изменения у сущностей. Мы знаем кто, как и когда изменил сущность. Но этот бандл не умеет отслеживать изменения в связующих таблицах многие-ко-многим. То есть у сущность новостей меняются теги и это не логируется. Надо чтобы логировалось
Konstantin
попробуйте поискать другие бандлы по ключевым словам doctrine и audit, их там было штуки 3-4 вроде
Kirill
попробуйте поискать другие бандлы по ключевым словам doctrine и audit, их там было штуки 3-4 вроде
другие вроде бы есть, но менять один на другой не хочется, там исторические данные за пару лет уже хранятся. Я вот хотел просто листенер написать и добавить недостающие данные к записи
Konstantin
мне кажется, что формат хранения если не одинаков будет, то очень-очень похож
Konstantin
но вообще, взрослые ребята делают аудит средствами базы, а не кодом, это адски дорого делать как вы, особенно, когда начнется нагрузка
Denis
Как работает DI конструктора в Symfony? К примеру есть 2 независимых, не связанных между собой метода(methodFirst, methodSecond) в сервисе MainService, которые используют каждый свой сервис(SubService1 и Subservice2), которые подключены через DI конструктора рассматриваемого сервиса (MainService). Можно ли так использовать подключение через DI даже в том случае если они при вызове не будут использоваться? Не будет ли это нерациональное использование памяти из-за создания там обеъектов через DI? Вопросы SRP-принципа пока не учитываем.
Konstantin
не, дополнительный инжект ссылки на инстанс сервиса памяти не жрёт, вам двойка по мемори-модели пхп, идите читайте что такое передача по ссылке
Юра
Он имеет в виду что хоть он не испльзует сервис но он будет создан
Юра
Да он будет создан если это не лейзи сервис
Konstantin
в общем и целом - не заморачивайтесь, инициализация сервиса должна быть лёгкой - не надо в конструкторе создавать какие-то тяжелые структуры данных, куда-то подключаться или делать тяжелую работу, то есть это такой lazy. но ручной. если прям без этого никак, то используйте lazy-proxy, но это уже крайняя степень отчаяния, в идеале всё должно быть нормально и без него
Denis
То есть выход в данном случае - делать сервис lazy или разбивать MainService на два разных сервиса?