• Проект со сложной логикой на Symfony – как проектировать? Примеры?

    TrogWarZ
    @TrogWarZ Автор вопроса
    Сергей Протько:
    Что за ужаный getService в неймспейсе Domain? А как же dependency injection?

    Случайно наткнулся на хабратред посвящённый сервис-локатору – походил по ссылкам, погуглил и ваша реакция здесь теперь понятна, спасибо.
    Вообще, тот `getService('mailer')` появился из-за того, что я обычно использую это в контроллерах фреймворка, на котором пишу чаще всего (Phalcon). Или магическую версию `$this->mailer` вместе с докблоками, содержащими типы указанных сервисов.
  • Как вывести числа от 1 до 10 равномерно в 3 колонки?

    TrogWarZ
    @TrogWarZ
    Immortal_pony: точно, показалось, что последний пример из вопроса – и есть то, что нужно. Но там выше уже предложили более корректные варианты ответа.
  • Проект со сложной логикой на Symfony – как проектировать? Примеры?

    TrogWarZ
    @TrogWarZ Автор вопроса
    Сергей Протько: начинаю улавливать, спасибо за терпение и объяснения! Пойду учить матчасть на эту тему.
  • Проект со сложной логикой на Symfony – как проектировать? Примеры?

    TrogWarZ
    @TrogWarZ Автор вопроса
    Спасибо, выглядит круто. Но я пока сначала почитаю про AOP поподробнее прежде чем это использовать.
  • Проект со сложной логикой на Symfony – как проектировать? Примеры?

    TrogWarZ
    @TrogWarZ Автор вопроса
    Сергей Протько: за реализацию спасибо, подсмотрю немного оттуда идей. Получатся, грубо говоря, что-то типа лога событий, который пишут хандлеры, а обработчики уже забирают эти события сами в своём режиме.
    Это как раз то, что я называл "асинхронным" (скажем, поставить в очередь задачу в beanstalk/rabbit/...) и, видимо, ошибся терминологией.

    Мне же нужен метод "отправить письмо курьеру о новой посылке" в доменной логике потому, что это действие диктует бизнес, а за это отвечает отдельный сервис, в который нужно послать задачу на работу.
    С учётом вышеизложенного, оно теперь будет находиться не в обработчике события, а в той части, которая будет разбирать массив событий. И, в том числе, слать письма.
    Возможно, мне стоит перечитать какую-нибудь главу из Зандстры на эту тему, однако хочется ещё и примера – ведь из слоя бизнес-логики нужно обратиться к "письморассылателю" чтобы он отправил письмо, а технические детали рассылки – уже его дело.
    Делать метод типа "уведомить курьера о новой посылке" мне кажется оверхедом просто потому, что в моём конкретно проекте будут только один канал связи – емейл и никак иначе. Однако, интересно было бы посмотреть на идею решения более опытного человека.
  • Проект со сложной логикой на Symfony – как проектировать? Примеры?

    TrogWarZ
    @TrogWarZ Автор вопроса
    index0h:
    Для простых ответов - достаточно в экшне сделать.

    Всегда jsonapi иначе расценивается как баг, со связями и т.д. Но так как ответ одинаков – не хочется дублировать. Хочу повесить на хук типа "afterResponse", пока не успел дочитать маны по Симфони на эту тему.

    Посему если есть возможность выполнить функциональность без ивент-лупа

    Я предполагал в лупе только ставить задачи на выполнение в какой-нибудь rabbitmq или любой другой асинхронный обработчик.
    Но тут ниже Сергей Протько уже предложил чуть более конкретное решение – DomainEvents – есть у меня подозрение, что вы говорите о том же (-: Идею понял, оно и правда кажется очень удобным, за это направление спасибо! Пока не успел изучить нормально чтобы были более-менее конкретные вопросы на эту тему.

    Security Voters – согласен. Выглядит удобно. Реализую. В моём случае достаточно будет проверять доступы к типам и параметрам типа. Гитлабом пользуюсь – очень похоже на то, что нужно, спасибо за наводку!

    Ага! OAuth scopes! Теперь понял о чём вы, благодарю!
  • Проект со сложной логикой на Symfony – как проектировать? Примеры?

    TrogWarZ
    @TrogWarZ Автор вопроса
    Сергей Протько: погуглил DomainEvents – почитал Фаулера (по перекрёстным ссылкам ещё не освежил), заглянул вот сюда и, если честно, не понял чем это отличается от обычной событийной модели, кроме названий не "в такой-то модели изменилось такое-то поле", а "кастомер положил себе продукт в корзину" или "посылка перешла в статус доставленной".
    Если не так понимаю, то пошлите меня, пожалуйста, по более направленным гуглозапросам/книгам/статьям на эту тему?

    а зачем вам они нужны?

    Например, при добавлении заказа послать письмо, отправить несколько запросов в разные внешние апи (асинхронно), добавить к ней курьера и выставить ему определённый статус.
    В данном случае мне видится разумным сделать так (пока что – я ни строчки ещё не написал, только проектирую):
    namespace \Acme\Domain;
    
    use \Acme\Domain\Commands;
    
    class Events\OrderHandler
    {
        public function onOrderCreated(Events\Event $event, Entities\Order $order)
        {
            // @todo Use ACL here
    
            // All actions are async
            $this->getService('mailer')->send('courier@example.com', 'New order!');
            $this->getService('externalApiName1')->exportOrder($order);
            $this->getService('externalApiName2')->exportOrder($order);
            $this->getService('commandBus')->handle(new Commands\Courier\DetectAndUpdateStatus($order->getCourier()));
        }
    }

    Насколько подобное решение адекватно? НЕ пахнет ничем непотребным?
  • Проект со сложной логикой на Symfony – как проектировать? Примеры?

    TrogWarZ
    @TrogWarZ Автор вопроса
    За идею спасибо, действительно, таким переносом можно упростить поддержку.
    Правда, в конкретно моём проекте юзеру не нужно быть даже в нескольких группах так что задача упрощается.
  • Проект со сложной логикой на Symfony – как проектировать? Примеры?

    TrogWarZ
    @TrogWarZ Автор вопроса
    Просто забудьте об этих ивентах.

    На что их заменить?
  • Проект со сложной логикой на Symfony – как проектировать? Примеры?

    TrogWarZ
    @TrogWarZ Автор вопроса
    Про микросервисы понял, спасибо за опыт (своего в этой архитектуре таки нет).

    Если в "сервис" вы вкладываете понятие простого класса, умеющего форматировать ответы вашего проекта - мысль здравая.

    Что-то в духе `\Acme\Frontend\ResponseRenderer\JSON::renderCollection(\Acme\Domain\Entity\BaseCollection $collection). Или, скорее всего, с использованием Transformer+TransformerManager как у `league/fractal` (или его Symfony-аналога).

    Если есть возможность отказаться от событийной модели - часто лучше отказаться.

    Функционал "PostBeforeEdit/PostBeforeEditHandler" часто дешевле

    Кажется, я вас не понял – поясните чуть подробнее? В моём понимании, доменная логика кидает события в названиями вроде `post.beforeEdit`, которое ловит обработчик `\Acme\EventManager\Post::beforeEditHandler($event)`. Отказаться от событийной модели в пользу какой другой?

    Насчёт иерархической ACL. Все группы будут известны на этапе проектирования, дополнительные через админку можно считать алиасами к уже известным. Где почитать (или по каким ключевым словам искать) способ сделать плоским наследование групп типа "manager может делать всё то, что и customer, но ещё вон то и вот это"? Резоннее и более поддерживаемо будет дублировать все права?

    Гибкая настройка вплоть до каждого поля 90% что не нужна.

    Есть уже известный сценарий: на странице заказов есть таблица с кучей данных, каждая юзер-группа (менеджер/кастомер/админ/аудитор/...) имеет доступ к разному набору этих данных, – возможно, имеет смысл хранить данную логику внутри трансформеров ответов от апи.
    Второй сценарий похож на первый за исключением того, что к каким-то полям этой таблицы юзер имеет права read-only. Видимо, я попадаю в те 10%? Или есть best practice с реализацией проще? По поводу скопов прав, коли они могут помочь решить сценарии, направьте меня, пожалуйста, в симфони-доки/библиотеку/гугло-запрос для дальнейшего изучения?

    Спасибо за ссылку на вопрос. Да, TDD-подход подразумевался по умолчанию поэтому его даже не упоминал (-:
  • Проект со сложной логикой на Symfony – как проектировать? Примеры?

    TrogWarZ
    @TrogWarZ Автор вопроса
    Спасибо за подробный ответ!
    Тесты не упоминал даже потому как без них в таком проекте можно сразу идти и закапываться, TDD по умолчанию.
    Про микросервисы понял, gitflow и версионирование именно в таком виде и использую.
    За направление в сторону DomainEvents и security voters спасибо! И за книги, –первую читал, но уже кучу лет назад.
  • Апгрейд Phalcon 1.x до 2.x стал потреблять всю ОЗУ – как обойти?

    TrogWarZ
    @TrogWarZ Автор вопроса
    UPD: https://github.com/phalcon/cphalcon/pull/12131 – Этот PR, видимо, будет вмержен в 3.0.1 и исправляет САБЖ.
  • Как выполнить запрос для каждой строки в таблице?

    TrogWarZ
    @TrogWarZ Автор вопроса
    Спасибо за ответ!
    То есть, повесить триггер, выполнить миграцию, убрать триггер? А как его вызвать вручную? Смотрю мануал, но не вижу.
    И будет ли это быстрее, чем курсоры в процедуре?
  • Апгрейд Phalcon 1.x до 2.x стал потреблять всю ОЗУ – как обойти?

    TrogWarZ
    @TrogWarZ Автор вопроса
    Насчёт потерь сеттера для связей – я был невнимателен. В коде из комментария ничего не потеряется.
  • Апгрейд Phalcon 1.x до 2.x стал потреблять всю ОЗУ – как обойти?

    TrogWarZ
    @TrogWarZ Автор вопроса
    Вот это дела. XhProf показывал, что Reflection тормоз, но до такого реквеста не добрался, спасибо! С переопределённым магическим сеттером скорость вернулась, правда я скопировал весь код из репо, а не только из комментария – иначе потеряется сеттер для связей.
    Почему используется некэшируемая и финальная рефлексия – загадка. Напишу им issue, конечно.
    В моей команде и проектах используются только геттеры/сеттеры извне реопзитория моделей так что не страшно да и на поведение `toArray` так же не влияет.
  • Использование нескольких ВК-приложений на PHP API – как не плодить условия на тип приложения?

    TrogWarZ
    @TrogWarZ Автор вопроса
    Константин: конечно, всегда можно навертеть дополнительных абстракций. Я хотел выяснить этот момент (так как опыта не имел ранее): либо можно проще, но я не могу, либо это действительно самое простое из возможных решений.
  • Использование нескольких ВК-приложений на PHP API – как не плодить условия на тип приложения?

    TrogWarZ
    @TrogWarZ Автор вопроса
    Да, всё верно поняли, спасибо за мнение! Успокоили.

    Я пока ждал ответов уже принял решение – взял в качестве библиотеки для социалок `league/oauth2-client` и в качестве адаптера для конкретно ВК `j4k/oauth2-vkontakte`.
    Затем в своём приложении создал два разных независимых адаптера: `vk-website` и `vk-standalone`, один из которых при `postOnWall()` возвращает всегда `true`, а другой реально постить запись.
    Пришлось "изобрести" свою фабрику и несколько адаптеров моего личного интерфейса (где библиотека – клиент адаптера), но оно оказалось достаточно тонким.
    А визуально для пользователя эти два адаптера уже мержатся на стороне браузерного клиента по логике "показать чекбокс что соцсеть подключена если хотя бы один из двух адаптеров имеет токен".
  • Какие впечатления от Phalcon по сравнению с Symfony / Yii?

    TrogWarZ
    @TrogWarZ
    Шустрый, подтверждаю.

    Правда, при переходе с 1.x на 2.x бывают очень внезапные странности, нигде не описанные, но зачастую очень критичные и не понятные.
    Например, на этой неделе столкнулся с тем, что при использовании с `thephpleague/fractal` метод `\Phalcon\Mvc\Model\Resultset\Simple::current` стал выедать 3+ Гб ОЗУ и тормозить на 30+ секунд запрос.
  • С чего начать в Scala (?) разработчику из PHP мира?

    TrogWarZ
    @TrogWarZ Автор вопроса
    Очень интересно выглядит проект по изучению, спасибо!
    API разные бывают – внутри может быть довольно много логики. И иногда (на моём опыте – чаще всего) функицонально писать лаконичнее и понятнее.