Nikolay
Сначала, чем проще тем лучше. Затем, если понадобится, то рефакторинг
Aleksandr
ужас в таком месте работать)
Юра
Ну вот такое решение приняло руководство. Сам в шоке
Aleksandr
пора валить)
Юра
У них их так текучка была сейчас станет ещё хужк
Сергей
В классе с названием цена добавлять какие-то купоны это странно. Класс тогда должен быть что-то типа Order. В нем должна быть ссылка на продукт с ценой и возможность добавлять купоны и иметь метод getPrice(DiscountCalculatorInterface $calculator). Думаю как-то так
Maks
ужас в таком месте работать)
я с таким сталкивался только на апворке) и что то никто особо не переживал
Владимир
Ну вот такое решение приняло руководство. Сам в шоке
"Вам шашечки или ехать" Если шашечки и платят не х2 от рынка, то проще свалить Ну вот нужно мне после время от времени переключиться, посмотреть видосик с чаем и т.п.
Вадим
class Price { public function calculateWithDiscount(int $tax, Coupon $coupon) { if ($coupon->type === CouponType::DiscountPercent) { .... } ... } }
так это получается тогда мне в Price придётся зависимости прокидывать если они понадобятся для расчёта скидки. Та же история что и с Купоном
Kirill
Я верю, когда-нибудь рекрутеры научатся читать описания чатов...
Kirill
ты еще предложи им резюме читать)
блин, может они просто читать не умеют? И в этом все проблемы?
Сергей
Привет. Подскажите, как сейчас в Симфони дела с ACL? Как я понимаю, основной способ это этот бандл: https://github.com/symfony/acl-bundle? Может есть какие-то другие решения, этот кажется слегка переусложненным. Воутеры и isGranted увы не подходят, у каждой роли разрешения на эндпоинты должны настраиваться динамически
Сергей
Никто не мешает на основе этой базовой системы что то свое написать.
Да это понятно, что интеграция до удобного состояния будет болезненной) Вопрос больше про то, не появилось ли каких-либо других решений, которые были бы чуть сложнее чем Воутеры, но чуть проще чем Акл Бандл, которые решают эту интеграцию вместо меня
Павел
Да это понятно, что интеграция до удобного состояния будет болезненной) Вопрос больше про то, не появилось ли каких-либо других решений, которые были бы чуть сложнее чем Воутеры, но чуть проще чем Акл Бандл, которые решают эту интеграцию вместо меня
Да в том то и дело, что вроде болей не должно быть, зато не будете запечатаны в какой то библотеке и ее возможностях. Ну это я так, понятно что не ответ на ваш вопрос о списках либ
Сергей
О какой боли идет речь? Внутри воутеров можно делат любую сложную логику
Может я чего-то недопонимаю? Можно с помощью Воутеров каким-то простым способом дать возможность динамически назначать для разных пользователей доступ к разным экшенам?
Сергей
Я пока вижу вариант хранить роли для каждого пользователя в виде массива доступов, а-ля ['edit_entity', 'view_entity', ...] и потом проверять их в каждом экшене через isGranted или воутера
Сергей
Кратко, да )
Не поделитесь чуть более полной версией?)
Елнур
Щас
Елнур
Например, есть сущность статья, есть эндпойнт редактирование. Нужно ли проверять, что именно к этой сущности есть право на редактирование? Или редактирование вообще всех статьей
Сергей
Только проверка на право дергать конкретный урл, или его отсутствие
Елнур
нет, проверка на доступ к конкретной сущности должна быть уже где-то внутри экшена
а можно и вместе делать, тогда логика прав доступа будет в одном месте. Внутри воутера можно вызывать любые ваши сервисы
Павел
Я пока вижу вариант хранить роли для каждого пользователя в виде массива доступов, а-ля ['edit_entity', 'view_entity', ...] и потом проверять их в каждом экшене через isGranted или воутера
Примерно так только можно через свой кастомный вотер, и смотреть не роли а что то другое (тот же массив прав). Просто если делать свой вотер будет чуть гибче если на какой то экшен будет чуть больше логики, чес просто посмотреть название пермишена
Елнур
is_granted можно вызывать двумя способами: - is_granted(attribute) - is_granted(attribute, entity)
Павел
is_granted можно вызывать двумя способами: - is_granted(attribute) - is_granted(attribute, entity)
Причем под entity не обязательно должна быть энтити, а что угодно
Павел
короче по факту это просто 2 атрибута
Елнур
is_granted можно вызывать двумя способами: - is_granted(attribute) - is_granted(attribute, entity)
в первом случае, в атрибут можно передать глобальное право: entity_view, entity_edit, entity_action во втором случае, право относительно сущности/объекта: edit, view, action
Елнур
а как внутри проверять - полностью ап ту ю... можно через роли пользователя, можно получать из отдельной таблицы acl, или согласно текущему состоянию сущности и т.д.
Елнур
к одному атрибуту у вас могут быть множество воутеров. Например, есть атрибут edit, один воутер может проверять по ролям, другой из асл таблицы, другой по другому и т.д.
Сергей
Примерно так только можно через свой кастомный вотер, и смотреть не роли а что то другое (тот же массив прав). Просто если делать свой вотер будет чуть гибче если на какой то экшен будет чуть больше логики, чес просто посмотреть название пермишена
А сам Воутер можно вызвать только из экшена через DI? Можно ли как-то определить глобальный воутер, который будет работать как middleware и проверять все приходящие экшены?
Сергей
в первом случае, в атрибут можно передать глобальное право: entity_view, entity_edit, entity_action во втором случае, право относительно сущности/объекта: edit, view, action
Чтобы не в каждом экшене передавать эти параметры а забирать их динамически, на основе имени контроллера и экшена?
Елнур
воутер пусть будет знать только про права и его логику
Павел
Чтобы не в каждом экшене передавать эти параметры а забирать их динамически, на основе имени контроллера и экшена?
Попытка сэкономить строки кода, обычно потом заканчиваются тем, что в этом обобщенном коде куча ифов и сложой логики, чтобы в итоге разделиться на какие то узкие кейсы
Сергей
воутеры вы не вызываете вручную... при проверке через is_granted симфони секюрити все делает за вас
А как в таком случае связываются экшен и сопутствующий ему воутер?
Елнур
А как в таком случае связываются экшен и сопутствующий ему воутер?
можно через атрибуты, можно вручную вызвать в контроллере
Елнур
думаю, вам лучше один раз посмотреть доки
Сергей
думаю, вам лучше один раз посмотреть доки
Да, пищи для ума как структурно простроить уже предостаточно, спасибо
Елнур
https://symfony.com/doc/current/security.html#access-control-authorization
Nikolay
Привет, у меня есть DTO, по данным которого нужно получить объект и сделать валидацию. То есть, нужно сначала провалидировать часть полей DTO, получить объект и на основе этого объекта еще провалидировать оставшуюся часть полей. Получается, что нужно делать валидацию два раза: сначала провалидировать сырые данные, затем уже более сложные проверки. Из идей пока что сделать два отдельных ДТО, но может есть и другие варианты
Nikolay
При мапе данных на дто они уже должны быть валидными. Можешь дать более конкретный пример?
В API прилетает запрос, создается DTO через десериализацию, затем валидируется. В этом DTO есть accountId, в более сложной валидации нужно достать account по этому идентификатору и сделать еще валидацию, что допустим доступны определенные настройки
Михаил
Плюс не путай валидацию и бизнес проверки - это разные слои
Nikolay
Так сущность внутри бд априори валидна
Сущность здесь только косвенно участвует, нужно проверить что-то на основе ее данных. Возможно, сейчас смешена валидация и бизнес проверки, но так сделано
Павел
Привет, у меня есть DTO, по данным которого нужно получить объект и сделать валидацию. То есть, нужно сначала провалидировать часть полей DTO, получить объект и на основе этого объекта еще провалидировать оставшуюся часть полей. Получается, что нужно делать валидацию два раза: сначала провалидировать сырые данные, затем уже более сложные проверки. Из идей пока что сделать два отдельных ДТО, но может есть и другие варианты
То что 2 валидации это нормально (как уже их назвать валидацией, бизнес проверки - дело десятое). Две дто делать не надо. По сути первая проверка - это проверка корректности данных по апи (грубо говоря проверка что соотвествует контракту) Вторая - более глубокая на основе БД, уже может быть в самом экшене
Павел
Но это оверинижиниринг, который очень редко когда помогает
Павел
Бывает иногда надо, когда например в 1 запросе участвует 2 экшена
Павел
Но для валидации мудрить имхо не стоит
Михаил
Сущность здесь только косвенно участвует, нужно проверить что-то на основе ее данных. Возможно, сейчас смешена валидация и бизнес проверки, но так сделано
Можешь сделать 2 объекта 1 - dto запроса 2 - контекст юзкейса Но прогонять одни и те же данные несколько раз через валидатор - риск того, что поменяешь правила валидации в одном объекте, но забудешь в другом
Nikolay
Но это оверинижиниринг, который очень редко когда помогает
Тут получается, что: 1. Валидируем сырые данные из запроса 2. Кастомная валидация
Михаил
1. Валидируем что сам запрос корректен 2. Валидируем что действие возможно Это нормально
Nikolay
Тогда ничего плохого нет
У меня возникли вопросы по поводу в каком виде делать эту кастомную валидацию
Михаил
У меня возникли вопросы по поводу в каком виде делать эту кастомную валидацию
В юзкейсе ифэлсами If account.amount < context.amount: throw «не достаточно средств»
Михаил
А лучше в сущности, если доменная логика лежит в ней (хотя это не всегда возможно)
Юра
Я бы не совмещал валидацию данных и бизнес правила
Nikolay
Я бы не совмещал валидацию данных и бизнес правила
Я бы тоже, но уже сделано так, что все в одном
Михаил
Я бы не совмещал валидацию данных и бизнес правила
Да, типо в валидаторе просто проверять что чтсла это числа, энамы - это энамы, массивы сущностей (вы поняли)
Юра
По теме https://youtu.be/FbYcIqVmGRk?si=RFl27y4auC0mR_8J
Null
Podlodka PHP Crew — это серия онлайн-конференций для php-разработчиков с упором на практическую пользу. Сессии проходят в удобное время утром и вечером, так что можно участвовать без отрыва от работы или отдыха. Уже 30 сентября стартует новый сезон, где обсудим архитектуру: - Как документировать сложные системы по модели C4, разберемся с Кириллом Сурогатовым (Oxagile); - Как выбрать между RabbitMQ и Kafka для обработки большого количества сообщений, обсудим на конкретных кейсах с Михаилом Камориным (Skyeng); - Лайвкодинг по Temporal — Алексей Гагарин, Павел Бучнев (Spiral Scout) наглядно покажут, как этот инструмент упрощает жизнь разработчикам; - Как ускорить работу PHP-монолита с RoadRunner, поделится Владимир Плахотников (Yclients). Каждый доклад — это готовое решение, которое можно внедрить в свой проект. Билеты и подробности на сайте: https://podlodka.io/phpcrew А промокод сообщества php_crew_5_TOyrjx даёт скидку еще в 500 руб🥳
Ivan
Ребят всем привет - у меня есть вот такое на старой симфонии stylesheets & less Не пойму как это запускается - может кто то подскажет - спасибо ——— <!DOCTYPE HTML> <html> <head> <meta charset="{{ _charset }}"> <title>{% block title %}{{ 'project_name'|trans }}{% endblock %}</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> {% stylesheets '@AppBundle/Resources/public_source_new/less/*.less' filter="?cutcomments,?yui_css" output='bundles/app/css/main_new.css' %} <link rel="stylesheet" href="{{ asset_url }}"> {% endstylesheets %} </head> ——— Есть вот такой плагин настройка package.json { "dependencies": { "less": "^4.2.0" } } ——— настройка в симфонии config.yml assetic: debug: "%kernel.debug%" use_controller: false filters: less: node_paths: [ "/usr/local/lib/node_modules" ] apply_to: ".less" yui_css: jar: "/usr/share/yui-compressor/yui-compressor.jar" yui_js: jar: "/usr/share/yui-compressor/yui-compressor.jar" — Как у меня получилось запустить less и собрать файл ./node_modules/less/bin/lessc 00-main.less main.css ./node_modules/less/bin/lessc ./src/KreaLab/AppBundle/Resources/public_source_new/less/00-main.less ./web/bundles/app/css/main_new_part_1_00-main_1.css
Ivan
Объясните пожалуйста Какая разница между первым и вторым? /** * Constructor. * * @param string $nodeBin The path to the node binary /usr/bin/node * @param array $nodePaths An array of node paths. /usr/local/lib/node_modules */ public function __construct($nodeBin = '/usr/bin/node', array $nodePaths = array()) {
Kirill
так там написано