Задать вопрос
  • Не могу подключить иконочные шрифты?

    @Flying
    .ai - это формат Adobe Illustrator, он явно не является шрифтом. Просто используйте реальные веб-шрифты (расширение должно быть .woff2 или .woff).

    Если у вас есть только desktop версия шрифта (к примеру с расширением .ttf или .otf) - то веб-версию можно получить используя FontSquirrel generator.
    Ответ написан
  • Контроль доступа в symfony, не совсем понимаю тебя?

    @Flying
    Symfony - это в первую очередь framework для обработки HTTP запросов и поэтому многие компоненты по-умолчанию "заточены" именно под этот сценарий.

    В конечном итоге вся Symfony Security построена вокруг понятия "токена" (TokenInterface) и большинство частей Security компонента достаточно абстрактны для того чтобы из них можно было собрать весьма разнообразные схемы разделения прав доступа.

    Вам необходимо определить для себя что означает "привязка привилегии к функционалу" с точки зрения кода приложения. Вы планируете оставить это разделение прав доступа на уровне "пускать / не пускать по определённому route" или вы будете в сервисах приложения вызывать что-то подобное Security::isAllowed()? Symfony по-умолчанию реализует первый подход, но ничто не мешает вам организовать собственную реализацию основных компонентов. Если вам нужен ACL (а именно так называется "привязка привилегии к функционалу") - то эта функциональность вынесена в отдельный ACL bundle в Symfony 4, скорее всего именно она вам и нужна.

    По поводу связки role = privilegy - нет, в общем случае это не так. Необходимо разделять процессы аутентификации (в результате которого подтверждается валидность пользователя и определяются его роли) и авторизации (в результате которого определяется может ли аутентифицированный пользователь получить доступ к тому или иному ресурсу).

    Если говорить о работе Symfony Security в контексте обработки HTTP запроса - то аутентификация производится в процессе прохождения запроса через т.н. firewalls, их задача - каким-либо образом определить что это за пользователь и сформировать token. Процесс авторизации построен вокруг т.н. voters которые "голосуют" за/против/воздержался по вопросу "пускать/не пускать", в документации есть целый ряд примеров. Надеюсь факт того что voters могут быть произвольными и иметь любую собственную логику - довольно очевиден. К примеру тот же ACL bundle как раз реализует voter который принимает решение о доступе на основе ACL list'а (который, конечно же, может находиться и в базе данных), но в целом это частный случай.
    Ответ написан
    1 комментарий
  • Как побороть, что fputcsv добавляет словам с пробелами двойные кавычки?

    @Flying
    Это связано с форматом CSV как таковым :) А также со значением аргумента $enclosure который вы, очевидно, оставили по-умолчанию. Всё это есть в документации.
    Ответ написан
  • Скорость работы MySQL или Файлы?

    @Flying
    Выбор сильно зависит от того что вы собираетесь делать с этими данными. Если вам нужно (и, главное, будет нужно и в дальнейшем) только читать / писать строго определённые одиночные записи - то можно использовать и файловую систему, хотя хранить все файлы в одной папке - очень плохая идея, нужен sharding чтобы оптимизировать работу (вспоминаем как работает поиск по файлам в каталоге). Кроме того нужно помнить что открытие файла - довольно дорогая операция.

    Если же вам сейчас или в дальшейшем потребуются операции затрагивающие множество элементов, поиск в них или, к примеру, агрегация - то ответ однозначный - база данных.

    Конечно есть много нюансов которые могут склонить чашу в ту или иную сторону и про которые вы не упомянули. К примеру если у вас файлы размерами в гигабайты и вам нужно выбирать оттуда какие-то мелкие части - то лучше использовать файлы, а не базу данных. Если у вас предполагается доступ к данным с нескольких компьютеров - то однозначно база данных.

    В целом ваш запрос сводится к "использовать ли мне программу, специально предназначенную для нужной мне функции или написать свой велосипед". Уверен что в подобной формулировке вам легче будет самому ответить на свой вопрос.
    Ответ написан
    Комментировать
  • Чем заменить PUG?

    @Flying
    Посмотрите в сторону Timber, он интегрирует Twig в Wordpress, работает весьма хорошо.
    Ответ написан
    Комментировать
  • Мобильная верстка — почему уменьшается масштаб сайта?

    @Flying
    Проверьте наличие в коде сайта настроек viewport'а, что-то вроде этого должно помочь:
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    Ответ написан
    1 комментарий
  • Как правильно верстать сайт с арабскими и хинди языком?

    @Flying
    Поскольку недавно пришлось добавлять в одном проекте арабский язык - поделюсь полученным опытом:

    Вёрстку как правило переделывать не нужно, обычно достаточно изменения стилей, но только в случае если сам сайт свёрстан с применением современных техник, в первую очередь flexbox. Если у вас там float'ы или таблицы - то ой, задача по сложности вырастет на пару порядков и почти наверняка не обойдётся без доработки html кода. Если же в этом аспекте всё в порядке и ваш проект построен на flexbox - то основная масса изменений сводится к одной строчке CSS:
    body {
        direction: rtl;
    }

    это "перевернёт" все горизонтальные flexbox'ы и по сути сделает за вас всю основную массу работы по адаптированию сайта к RTL языкам. Конечно, в зависимости от того как именно у вас будет подключаться стиль (отдельные стили для RTL или только патч или всё вместе) реальный селектор может быть, к примеру html[dir=rtl] + body, но это уже детали.

    Тем не менее, даже если flexbox автоматизирует для вас кучу ручного труда - есть целый ряд ситуаций когда необходимы доработки вручную. Основных направлений несколько:

    1. Горизонтальные отступы. Это самая большая часть работы по адаптации т.к. вам необходимо будет "перевернуть" и их тоже, заменив, к примеру, margin-left на margin-right и наоборот, то же самое для padding'а
    2. Абсолютное / относительное позиционирование в горизонтальной плоскости. Речь идёт о свойствах left и right, их, как можно догадаться, тоже необходимо поменять местами
    3. Размеры шрифтов. Поскольку, к примеру, арабский шрифт, обычно выглядит меньше и тоньше чем, к примеру, английский - возможно возникнет потребность увеличить размеры шрифтов (font-size, line-height) и, возможно, подстроить стилизацию (font-weight)
    4. text-align - в ряде ситуаций может потребоваться изменить его на противоположный
    5. :first-child и :last-child, стоит быть внимательным и перепроверить корректность получаемого результата, к примеру если к этим псевдо-элементам добавляется дополнительный отступ - вам, возможно, придётся менять местами и селекторы
    6. Нужно адаптировать визуальные элементы содержащие направление, к примеру стрелки / уголки и т.п. В ряде случаев их можно повернуть, но где-то необходимо будет рисовать отдельную версию


    Если вы используете CSS препроцессоры - то я очень рекомендую написать mixin'ы для рендера этих свойств и адаптировать код таким образом чтобы изменяющиеся стили рендерились через них. Я выложил набор mixin'ов которые использовал в своём проекте, среди них нет mixin'ов для отступов и шрифтов т.к. у меня эти вопросы решаются по-другому, но думаю что там не будет ничего сложного.

    Общая схема адаптации которую я использовал в проекте:
    1. Добавление direction: rtl
    2. "Переворачивание" отступов, это самая большая часть работы т.к. они чаще всего встречаются
    3. Проверка вёрстки, для каждого выпавшего элемента добавление патчей с использованием mixin'ов, ссылку на которые я дал выше
    4. Подбор изменений для шрифтов, адаптация шрифтовых параметров


    Пример выдернутого наудачу из проекта куска для демонстрации патчей, это стиль добавления иконки к строке текста, для RTL языка её нужно было опускать ниже:
    &.with-icon {
        $icon-size: 1.85em;
        @include offset(h $icon-size 0);
    
        &:before {
            // Позиция иконки меняется на противоположную
            @include hpos($left: -1em, $auto: true);
            font-size: $icon-size;
            // Подстраивается высота иконки относительно текста
            @include ltr() {
                top: 45%;
            }
            @include rtl() {
                top: 65%;
                // Стоит обратить внимание что для RTL языков иконка дополнительно переворачивается, 
                // там стрелка, так что работает нормально, но в других местах это может быть по-другому
                transform: translateY(-50%) rotate(180deg);     
            }
        }
    }


    Надеюсь это описание будет полезным :)
    Ответ написан
    2 комментария
  • Аналог команды cp -r в Windows?

    @Flying
    В принципе есть порты множества Unix утилит на Windows, в частности в рамках проекта GnuWin32. Конкретно cp находится в CoreUtils. Я пользуюсь уже много лет - во многом обеспечивает близкое к Unix окружение, с поправкой на ограничения cmd.exe конечно, зато нативно, без CygWin.
    Ответ написан
    Комментировать
  • Как правильнее реализовать код обработки AJAX запроса от разных сущьностей к одному контроллеру?

    @Flying
    В зависимости от реальных потребностей вашего приложения можно посмотреть в сторону использования наследования entities. К примеру возможно ваши "category, faq, article" являются частными случаями общей логической сущности Content, в этом случае можно было бы запрашивать репозиторий именно для базовой entity и дальше у вас не будет разделения логики работы с теми же тегами.

    Кроме того ничто не мешает вам вынести код работы с тегами в отдельный сервисный класс (назовём его TagSearchService), сделать для каждого типа "category, faq, article" отдельные actions в их контроллерах которые будут обращаться к сервисному классу с разными (и в этом случае заранее известными) параметрами. Т.е., проще говоря, в каком-нибудь CategoryController::search() вы могли бы вызвать TagSearchService и передавать ему Category::class вместо того чтобы полагаться на приходящие извне данные. Если переходить на такую схему - то разные классы для элементов форм (CategoryType и FaqType в вашем примере) тоже естественным образом заменяются на один класс (какой-нибудь TagSearchType) т.к. между ними не остаётся различий. Кроме того не нужно будет передавать извне имя класса - по-моему это плохая идея в любом случае.

    Если развивать эту идею дальше - то логично вырисовывается интерфейс TaggableInterface для entities которые могут иметь теги. Это естественным образом приводит к возможности в compiler pass собрать список таких entities и передать их в TagSearchService. Возможно потребуется для каких-то целей :)

    Далее, по поводу фильтрации тегов. Всё-таки при построении запросов мы ведём речь о DQL, так что есть ненулевой шанс (хотя доказать это я и не могу, надо пробовать) что вытаскивать id из тегов не нужно, достаточно передать массив самих entities в notIn(). Если же это и не так - код можно переписать с использованием array_map(), возможно это сделает его понятнее. Также findOneBy(['id' => $entityId]) очевидным образом меняется на EntityManager::find() что несколько проще выглядит.

    Насчёт идеи вытягивать именно id тегов - вряд ли в этом есть особый смысл если только у вас не очень нагруженное приложение.
    Ответ написан
  • Есть ли хорошие курсы по Symfony?

    @Flying
    Есть официальная учебная платфома у SensioLabs, правда недешёвая.
    Ответ написан
    Комментировать
  • Почему regEx не работает в firefox?

    @Flying
    regex101 тоже не может разобрать вашу регулярку, так что видимо вопрос в синтаксисе. Да и парсить адрес регуляркой - так себе идея, что вы будете делать если последовательность элементов в адресе будет другой или если там будут опечатки?

    Возможно вам стоит рассмотреть использование внешних сервисов которые нормализуют адреса? К примеру я в одном проекте использовал DaData и они действительно хорошо работают (не реклама :) ).
    Ответ написан
    4 комментария
  • Как сделать такую фигуру с помощью css?

    @Flying
    Для реализации на CSS потребуются как минимум conic-gradient() и CSS Masks, и то и другое весьма далеко до широкой поддержки браузерами, поэтому гораздо проще будет просто сделать SVG картинку.
    Ответ написан
    2 комментария
  • Как сделать связь одного поля таблицы с несколькими сущьностями (entity)?

    @Flying
    Вы уже используете DiscriminatorMap который является правильным решением в данной задаче. Вам ничто не мешает теперь иметь в наследуемых классах отдельные свойства содержащие связи с конкретными entities, специфичными для каждого конкретного типа пункта меню. Вы также вполне можете объявить getEntity() / setEntity() в классе MenuItem абстрактными, а в дочерних классах реализовывать их. Конечно типы на уровне языка вам будет не задать, но никто не будет вам мешать использовать PHPDoc для создания type hints.
    Ответ написан
    1 комментарий
  • Почему Firefox не всегда предагает сохранить пароль?

    @Flying
    Сохранение пароля не предлагается если сайт использует нестандартную работу с формами. К примеру если вместо сабмита формы происходит отсылка содержимого через AJAX запрос, если сами элементы формы находятся не в теге <form>, если вместо кнопки submit'а используется что-то другое (например ссылка с JavaScript обработчиком) и т.п. Кроме того сохранение формы не предлагается если сайт напрямую это запрещает, добавляя атрибут autocomplete="false" в элементы форм.

    Я как правило в этих случаях открываю dev tools, удаляю всю нестандартную обработку, добавляю обычную кнопку, удаляю ненужные атрибуты, заполняю логин / пароль, жму submit, сохраняю логин / пароль и перегружаю страницу. В 95% случаев помогает, единственный нюанс появляется в случае запрета на autocomplete - в этом случае при клике на поле логина Firefox предложит выбрать сохранённый логин и при выборе заполнит пароль.
    Ответ написан
    1 комментарий
  • Для чего предназначена данная примесь?

    @Flying
    Этот код проверяет что элементы в $map расставлены в порядке возрастания значений
    Ответ написан
    Комментировать
  • Слои приложения в Symfony?

    @Flying
    То что описано в пункте про "атомарные операции" больше всего похоже на методы в entity repository в Doctrine.
    • Если эти операции специфичны для каких-то конкретных entity - можно реализовывать прямо в методах соответствующих репозиториев
    • Если они общие для всех entities - то проще всего вынести их в промежуточный абстрактный repository и наследовать остальные custom repositories от него
    • Если они общие для части entities - можно, к примеру, определить дополнительные интерфейсы, показывающие какие операции применимы к каким entities (у меня, например, зачастую используется ActivitableInterface для entities для которых есть флаг isActive) и дальше либо реализовать промежуточный абстрактный класс репозитория и наследовать custom repositories от него либо вынести эти операции в traits и подключать по мере необходимости.



    Про "команды" не очень понятно, это про класс Command из symfony/command? Если да - то там есть раздельная инициализация через initialize(), туда передаётся OutputInterface и если сильно нужно - можно там вызвать некий отдельный сервис. Если не хочется прокидывать сервис вручную в каждую команду - можно автоматизировать это через setter + compiler pass либо через аннотицию @required
    Ответ написан
    2 комментария
  • Какие сетки вы используете в своих проектах? И куда двигаться дальше?

    @Flying
    Использую Susy (пока что 2-ю версию в силу ряда причин, но вообще рекомендую 3-ю). Причина выбора - возможность строить произвольные сетки (в том числе нерегулярные) при полном отсуствии навязывания каких-либо технологий реализации сеток. Мне в этой библиотеке нравится именно её гибкость т.к. она даёт только математику сетки. Одновременно с этим для новичка подобный подход может оказаться слишком сложным, но познакомиться с ним imho стоит. На самом деле сделать базовую сетку самостоятельно - очень несложно, особенно если использовать препроцессоры, имеет смысл разок попробовать ее реализовать.

    Один из моментов который не очень хорошо решается "стандартными" сетками - отсутствие поддержки внешних отступов внутри контейнера когда сетка должна занимать не всю ширину, а (ширину минус отступы). Конечно это решаемое ограничение, но оно имеет место быть. Подход bootstrap с заданием сетки через CSS классы лично мне не нравится т.к. порождает кучу лишних CSS классов которые в случае смены layout'а необходимо менять в коде (а не в стилях) проекта. Но здесь опять же кому что, да и у подхода с CSS классами есть свои плюсы - можно дать возможность бОльшего контроля layout'а разработчикам.

    Также стоит отметить что "правильных" сторон нет, есть множество подходов с которыми стоит ознакомиться и из которых нужно уметь выбрать тот который лучше подходит для решения задачи.
    Ответ написан
    Комментировать
  • Symfony 4 - Best Practices for Reusable Bundles в чём смысл, и как всё таки создать bundle?

    @Flying
    Очевидно вы имеете в виду вот эту статью в документации Symfony.

    Если прочитать текст более внимательно - то там не сказано что bundles теперь запрещены или не приветствуются. Речь идёт о том что bundles стоит использовать в том случае если вы хотите оформить часть своего кода в отдельный package который можно использовать и в других проектах. Основное же приложение теперь не стоит оформлять в виде bundle, а можно писать напрямую. Предлагается не складывать в /src кучу разных bundles, а иметь один общий код приложения, зависимый только от внешних packages (пусть даже написанных вами) которые устанавливаются через Composer.

    Т.е. к примеру структура кода подобная Sylius теперь не считается хорошей практикой.

    Думаю что одна из причин такого изменения - переход на Symfony Flex и автоматизированную поддержку регистрации / конфигурации bundles через recipes.
    Ответ написан
    Комментировать
  • Как компилируются пути из scss в css?

    @Flying
    Sass ничего не знает про ваши пути до картинок, указание корректных путей - ваша задача. Пути должны указываться относительно CSS файла, а не SCSS т.к., очевидно, они будут использоваться только когда CSS файл будет загружен в браузер.

    По поводу "локально запускается": проверьте что ваши пути в итоге не уходят выше document root сайта т.к. если это так - то они, очевидно, недоступны извне.
    Ответ написан
    4 комментария