Задать вопрос
  • Как кэшировать данные выполнения sql запроса в symfony 4 + doctrine?

    @dosim86
    Можете предварительно настроить кеширование в Symfony для Doctrine:
    framework:
        cache:
            pools:
                doctrine.result_cache_pool:
                    adapter: cache.app
    services:
        doctrine.result_cache_provider:
            class: Symfony\Component\Cache\DoctrineProvider
            public: false
            arguments:
            - '@doctrine.result_cache_pool'
    doctrine:
        orm:
            result_cache_driver:
                type: service
                id: doctrine.result_cache_provider

    По умолчанию Symfony использует файловое кеширование для пользовательских данных, поэтому результаты запроса Doctrine также будут хранится в файле. Однако если, например используете Redis, то можно его указать в качестве хранилища кешей по умолчанию:
    framework:
        cache:
            # Redis
            app: cache.adapter.redis
            default_redis_provider: '%env(REDIS_URL)%'

    Далее в нужных запросах просто указывайте Doctrine-е, что результат запроса надо кешировать:
    ...
    ->getQuery()
    ->useResultCache(true) // кешировать результат данного запроса
    //->setResultCacheLifetime(3600) // время жизни кеша при необходимости
    ->getResult()
    Ответ написан
    Комментировать
  • Как должен выглядеть symfony контроллер предназначенный для работы с CKEditor бандлом?

    @dosim86
    По идее нужно получить в контроллере загруженное через CKEditor изображение, обработать, сохранить и вернуть ссылку обратно к CKEditor. Далее CKEditor должен вставить ссылку в редактор. Также попробуйте прикрутить к CKEditor менеджер responsive filemanager
    Ответ написан
    Комментировать
  • Как в symfony 4 указать ссылку на другую сущбность при связывания в анатациях?

    @dosim86
    Связать сущности между собой возможно тольки при участии хотя бы одного первичного ключа этих сущностей, т.к. Doctrine различает сущности, благодаря первичному ключу, как и в теории базы данных в принципе. Таким образом в данном случае поле system_key не характеризует сущность А в целом, а просто является одним из его аспектов наряду с другими полями. То есть нужен критерий по которому можно однозначо различить сущность класса А от другой сущности того же класса. Таким критерием, как уже поняли, и выступает поле id, т.е. первичный ключ по которому различают одну запись от другой

    Свойства mappedBy, inversedBy в аннотациях ManyToOne, OneToMany следует указывать только если нужна именно двунаправленная связь между сущностями, т.е. когда В доступен из А и наоборот. Если требуется однонаправленная связь, т.е. достаточно из В получить А, то Doctrine-е надо явно указать связываемые поля через JoinColumn. В данном случае достаточно манипуляции с классом B, например:
    class B
    {
        /**
         * @ORM\ManyToOne(targetEntity="A")
         * @ORM\JoinColumn(name="a_id", referencedColumnName="id")
         */
        private $address;
    }
    
    class A
    {
        // ...
    }

    где, name="a_id" - поле таблицы B, referencedColumnName="id" - первичный ключ таблицы A
    Ответ написан
    Комментировать
  • Сервис с переведенным словарем параметров. Что-то не так?

    @dosim86
    Существующий подход вполне уместен, т.к. доступ к сервису из модели - это плохая практика и отображение локализованного текста из модели - это не задача модели, хотя поле name можно изменить на тип json в СУБД.

    В данном случае рекомендую переименовать сервис StaticList на ComissionManager и не делать статическим методы getCommissions и getTextForKey, т.к. конструкция self::$translator все равно требует начальной ручной инициализации объекта класса Translation, то пусть этим занимается неявно сам конструктор. Далее уже сервис ComissionManager достаточно внедрять как зависимость в нужном методе контроллера и вызывать $сomissionManager->getTextForKey($model->commission_key), подставляя модель явно, но можно короче и гибче $сomissionManager->getText($model).

    Конечно можно пойти дальше и создать интерфейс ComissionInterface c методом getKey и добавлять его к моделям, которые будут работать с комиссиями. Тогда реализация метода getText будет выглядеть так:
    public getText(ComissionInterface $model)
    {
        $key = $model->getKey();
        $text = ...
        return $text;
    }

    Таким образом сервису ничего не нужно знать о моделях, т.к. достаточно того, что они реализуют интерфейс ComissionInterface, который гарантирует, что метод getKey точно будет в модели. Т.е. абстрагируемся от конкретных классов моделей.

    У Вас типичная ситуация когда люди пытаются решить проблему одним большим методом или классом. Следуйте принципу единственной ответственности класса и метода.
    Ответ написан
  • Как лучше реализовать аутентификацию REST API?

    @dosim86
    Можно создать подписчика на kernel.request и развивать эту мысль:

    public function onKernelRequest(GetResponseEvent $event)
        {
            if (false !== strpos($event->getRequest()->getRequestUri(), '/api/')) {
                if (!$this->security->isGranted('ROLE_USER')) {
                    throw new NotFoundHttpException();
                }
            }
        }


    Также можно воспользоватсья бандлом FOSRestBundle
    Ответ написан
    Комментировать
  • Как дебажить references в fixtures doctrine? Или как вывести все reference?

    @dosim86
    Если решили работать с references в DoctrineFixtures, то обязательно нужно учитывать зависимости между фикстурами. В данном случае, и вообще в принципе, неизвестно в каком порядке нужно создавать фикстуры статьей и авторов, чтоб можно было статье присвоить уже созданного автора. И этот порядок надо явно указать в классе фикстуры, реализовав метод getDependencies интерфейса DependentFixtureInterface (из пакета Doctrine).

    Так как только статья зависит от автора, то достаточно это указать в фикстуре статьи, например:
    class ArticleFixture implements DependentFixtureInterface
    {
        // ...
    
        public function getDependencies()
        {
            return [
                UserFixture::class,
            ];
        }
    }

    И теперь сначала будет создан пользователь, а потом статья и можно быть уверенным, что пользователь не будет null при $author = $this->getReference('main_user');
    Ответ написан
    Комментировать