• Как сделать переключение чанков через список или радио кнопку?

    an-tar
    @an-tar Куратор тега MODX
    Full stack web developer
    А через что создаете конфиги? Например, в ClientConfig есть тип Selectbox (xtype: modx-combo), он мог бы помочь, если я верно вас понял.
    Ответ написан
    6 комментариев
  • Какой плагин для маски номера посоветуете?

    sfi0zy
    @sfi0zy Куратор тега JavaScript
    Creative frontend developer
    его проблема в том, что в заявку с формы он передает сам номер, но уже без кода страны

    Этот плагин может создавать скрытый инпут с полным номером. Если вы используете старомодные формы, то это именно то, что нужно.
    Ответ написан
    Комментировать
  • Как обновить codium plugin для PyCharm?

    Elaryks
    @Elaryks
    Включите VPN, после чего обновляйте плагин.
    Ответ написан
    Комментировать
  • Как добавить кнопки zoom на Яндекс Карту?

    yesbro
    @yesbro
    Думаю, помогаю думать
    YMapZoomControl импортируется из другого места. Сам недавно матерился по этому поводу. У них все самое полезное можно в примерах найти https://yandex.ru/dev/jsapi30/doc/ru/examples/case...

    const {YMapZoomControl} = await ymaps3.import('@yandex/ymaps3-controls@0.0.1')
    Ответ написан
    2 комментария
  • Пустая страница при деплое, как исправить?

    alsolovyev
    @alsolovyev
    ¯\_(ツ)_/¯ Enjoy life, Eat well & Laugh often
    Если вы просто открываете index.html в браузере, то у вас должны быть ошибки в консоле. Что-то тип:
    [Error] Origin null is not allowed by Access-Control-Allow-Origin. Status code: 0
    [Error] Failed to load resource: Origin null is not allowed by Access-Control-Allow-Origin. Status code: 0 (index-n_ryQ3BS.css, line 0)

    Не дает загрузить файлы из-за безопасности.
    Запустите какой сервере простой (live-server или python3 -m http.server) или используйте vite preview:
    // package.json
      "scripts": {
        // ....
        "preview": "vite preview"
        // ....
      },
    Ответ написан
    2 комментария
  • Как тестировать запросы и ответы из базы данных через phpunit?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Мне кажется, что найденные варианты работают не так. Используются они оба, а какой именно - зависит от того, что именно вы тестируете - запрос или ответ.

    Если говорить про "запросы к БД", то для таких тестов "массив с данными" использовать просто глупо. Это получится какой-то формальный тест: "проверяем, что метод возвращает массив из трех строк - и тут же возвращаем этот самый массив". В чем смысл? Если вы тестируете запрос к БД, то и надо тестировать запрос к БД. По-другому никак.

    Здесь я отвлекусь, и порассуждаю на тему того, что на самом деле тестирование - это гораздо более трудоёмкая задача, чем обычно считается. И как следствие, большая часть тестов - это такая вот туфта. Либо тест заранее возвращает нужные данные, либо тестирует один-два кейса. А вариантов неправильных входящих данных ведь может быть огромное количество. То есть по-хорошему на такой заведомо сложный (и принципиально неделимый!) метод нужно десятка два тестов.

    И сюда же использование для тестов БД другой системы. Например основная БД MySQL, а для тестов используется Sqlite. Тут сразу можно сказать, что это профанация. Различие даже в какой-то одной настройке БД может повлиять на результаты запроса (и теста как следствие) - а тут и вовсе используется совсем другая БД.

    С другой стороны, работу с БД скорее стоит тестировать не в юнит тестах, а скажем в интеграционных. Но не будем углубляться.


    Массив же "с данными, симулирующими ответ из базы данных" используется на следующему уровне, там где требуется "ответ из базы данных". Взьмём метод, который использует данные, полученные из БД. Например авторизация юзера. Этот метод должен не сам лезть в базу, а дёргать отдельный метод, вполне возможно, что совсем другого класса. И вот чтобы протестировать авторизацию, вы и мокаете метод для работы с БД, и из этого мока возвращаете тот самый массив без всякого обращения к бд.

    Здесь нелишне будет напомнить название доклада с одной из последних конференций по пхп. Дословно не помню, но что-то вроде "Делайте методы как можно короче. Ваши тесты скажут вам спасибо." Собственно, именно при тестировании очень быстро начинаешь понимать удобство атомарных (то есть выполняющих какую-то одну простую операцию) методов. А без тестов пройдёт довольно много времени, пока не понадобится этот длинный метод отрефакторить, и по итогам менять кучу кода, который его вызывает.

    Так что разбивайте ваши длинные методы на мелкие, и тогда вопрос, как их тестировать, в большинстве случаев отпадёт сам собой.
    Ответ написан
    1 комментарий
  • Совместимы ли блок питания и ноут?

    CityCat4
    @CityCat4
    //COPY01 EXEC PGM=IEBGENER
    А надо было проверить. БП у нас выдает 19V, 6.32A. А ноут потребляет 19.5V, 9.23A - ощущаешь разницу? БП выжимается "досуха" - и все равно его не хватает. Меняй.
    Вот, например в Чип и Дипе - ровно по параметрам - 19.5V, 9.23A
    БП, работающий на пределе, вполне способе сгореть. Буквально, с огнем и дымом. И мерзким запахом паленого пластика.
    Ответ написан
    Комментировать
  • Как избежать загрузки video пока оно не требуется?

    402d
    @402d
    начинал с бейсика на УКНЦ в 1988

    Есть js скрипт добавления нескольких video тегов

    который работает неправильно , значит вместо него надо написать работающий правильно.
    Или прочитать / разобраться в существующем как он устроен и переписать под себя.

    А не добавлять костыли снаружи.

    Логика всех скриптов Lazy Load основана на том, что сперва есть плейсхолдер, который заменяется на реальный контент при входе объекта в область видимости.
    Ответ написан
    Комментировать
  • Лучшие практики для русскоязычных аббревиатур в API?

    fox_12
    @fox_12
    Расставляю биты, управляю заряженными частицами
    Если предполагается в перспективе использование вне РФ - то лучше использование tin вместо inn, и прочие по возможности таким образом заменять.
    Ну а если сугубо для внутреннего пользователя - то можно использовать русские транслитерированные аббревиатуры.
    Ответ написан
    Комментировать
  • Как сверстать 3 колонки, чтобы текст по краям заходил на центральную колонку?

    copyhold
    @copyhold
    вам поможет свойство
    shape-outside
    Ответ написан
    Комментировать
  • Как обеспечить невозможность извлечения шрифтов с сайта?

    Mike_Ro
    @Mike_Ro
    Python, JS, WordPress, SEO, Bots, Adversting
    Разве возможно запретить скачать файл шрифта и при этом использовать этот шрифт?

    Нет. Все что "загрузилось браузером" - доступно для скачивания.

    Лицензируйте шрифт, затем ищите сайт, который использует шрифт без лицензии, нотариально заверяйте каждый год использования, затем, через 3 года подавайте в суд.
    Ответ написан
    7 комментариев
  • Как обеспечить невозможность извлечения шрифтов с сайта?

    @aleks-th
    Технически.
    Никак.
    Права на шрифт можно только юридически в суде защитить.
    На сайте все что загрузил браузер уже лежит на компьютере пользователя.
    Ответ написан
    3 комментария
  • Как должен выглядеть идеальный контроллер?

    Если хотите идеал, то он должен соответствовать следующим пунктам:

    1. Сериализация/десериализация - это дорогостоящее мероприятие, поэтому оно должно делаться только в двух местах: прямо на входе и прямо на выходе. Вход - это ваш контроллер, Выход - это другой сервис, куда вы передаёте данные, или база данных (тут тоже происходит сериализация, либо явно, либо в ORM). Во всех остальных слоях инфообмен должен совершаться уже при помощи объектов PHP либо нативных типов. Это экономит ресурсы. При передаче между слоями приложения объектов вместо значений либо ассоциативных массивов вы сразу будете видеть очепятки, IDE вам прекрасно поможет при помощи автодополнения, объекты могут иметь какие-то полезные методы.

    2. Очень желательно в каждом из слоёв иметь собственный класс, отвечающий за данные. Например, нам в слой API приходит JSON-чик с новым пользователем.
    - Сериализуем JSON в DTO UserInAPI, сразу валидируем всё то, что мы можем валидировать без слоя бизнес-логики, и либо отдаём клиенту ошибку, либо передаём сам объект UserInAPI в следующий слой: слой бизнес-логики
    - В слое бизнес логики, получаем DTO UserInAPI на входе, преобразуем его в свой бизнес-объект UserInBusiness, валидируем его уже с точки зрения бизнеса, и либо возвращаем ошибку в слой API, либо совершаем над ним действия, и передаём объект класса UserInBusiness в слой работы с базой
    - В слое работы с базой данных получаем на входе объект UserInBusiness, преобразуем его уже в сущность базы данных UserInDB, валидируем всё на предмет корректности данных для базы, и либо возвращаем ошибку в бизнес, либо сохраняем сущность класса UserInDB в базу.

    Зачем такие сложности, вы спросите? А просто обратите внимание на то, что скорость изменения кода в разных слоях разная.
    - API вообще должен меняться раз в сто лет, чтобы не злить клиентов. Поэтому DTO класс UserInAPI будет стабильным и редко будет меняться.
    - Бизнес-логика меняется очень часто. У класса UserInBusiness постоянно будут добавляться поля и методы, тут жизнь будет кипеть.
    - Слой базы данных будет меняться реже, чем слой бизнеса, но чаще, чем слой API, потому что нам нужны будут новые поля в базе, новые таблицы и связанные таблицы.
    - И если мы один тип сущности протащим во все слои, то эта сущность обрастёт таким количеством различной хрени, что нам плохо станет, когда будем на неё смотреть. Либо она обрастёт кучей декораторов в каждом из слоёв. Поэтому лучше всё разделить.

    3. Теперь внимание, казалось бы, что мы слишком сильно связываем наши слои, и нижестоящие слои знают что-то о вышестоящих, а это неправильно. Ведь мы передаём объект UserInAPI в слой бизнеса, т.е. слой бизнеса должен уметь работать с этим объектом. И так же слой базы должен уметь работать с объектом бизнеса UserInBusiness. Как же быть? А очень просто. На входе слоёв использовать интерфейсы. Т.е. в слое бизнеса мы будем принимать не сам класс UserInAPI, а объект, имплементирующий интерфейс UserIncoming, который объявим в бизнес слое, и заставим слой API сделать так, чтобы его класс UserInAPI имплементировал этот интерфейс. Таким образом слой бизнеса ничего не будет знать о слое API, а будет ждать на входе данные по контракту, описанному в интерфейсе. Бизнесу плевать на конкретную реализацию, ему нужны только методы getUsername, getEmail из интерфейса. А какой класс ему их предоставит - пофигу. Таким образом мы практически полностью разделяем слои и в два счёта сможем поменять слой API, где у нас HTTP контроллеры, на слой RabbitMQ, SOAP, Grpc и т.д.
    Ответ написан
    6 комментариев
  • Как войти в GitHub?

    вот и иллюстрация того, почему второй фактор в виде смс - это очень плохо.
    Используй recovery code, если ты заранее их сохранил.
    Если нет - попробуй самую нижнюю ссылку (которая "Try 2FA account recovery")
    Если и то не поможет - пиши в поддержку.

    Please contact support if you continue to have
    problems.

    Белым по красному же написано
    Ответ написан
    1 комментарий
  • Что такое /var/www/html/index.html и как отнять у него 80 порт?

    Файл не может "хоститься на порту". Порт занимает какая-то программа, команда netstat -tulpn | grep :80 её покажет.
    Вы либо недоубрали Апач, либо у вас Nginx ещё есть или какой-то другой веб-сервер. Содержимое файла ещё может дать подсказку.
    Ответ написан
    Комментировать
  • Правильно ли я написал html разметку по БЭМ?

    Сложная попытка описать все-в-одном. Попробуй начать это делать сразу от body (сарказм).
    На твоем скрине 4 разных блока - вот и описывай их отдельно.
    Перечитай еще раз про элементы и особенно про назначение модификаторов.
    Модификаторы не должны пытаться заменить элементы, но представляют собой вариацию элемента.
    В модификаторах пиши нижние подчеркивания вместо дефисов - надо думать и о других людях, классы с дефисами не удобно копипастить.
    Ответ написан
    3 комментария
  • Как организовать оптимальную безопасность для своего онлайн мультиплеера на Android?

    Steel_Balls
    @Steel_Balls
    0L3QsNGH0LjQvdCw0Lsg0YEgQkFTSUMg0L3QsCDQo9Ca0J3Qpi
    Ты всё правильно рассуждаешь.
    Исходить из принципа: все клиенты - мошенники.
    0% доверия клиенту.
    Не хранить у клиента никакой информации.
    Клиент - это только рендеринг данных.
    Вся логика - на сервере.

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

    Защита от подмены данных делается простым старым дедовским способом - подписью.
    На сервере и на клиенте есть одинаковый временный ключ для подписи - signKey - длинная строка.
    Клиент отправляет тебе POST-запрос со всеми данными: тип монеты, количество монет, ID юзера,...+ sign=HASH(тип_монеты+количество+userId+...+signKey)
    HASH - это хэш-функция. Лучше использовать Bcrypt вместо слабого MD5.
    Во-первых, всё делается через HTTPS.
    Во-вторых, все операции - через сессии или аутентификацию по JWT.
    На сервере ты делашь следующее:
    - проверяешь соответствие переданных данных ожидаемым: userId (из JWT), тип монеты и прочее. От клиента ты ожидаешь МИНИМУМ изменяемых данных (количество фишек, например)
    - проверяешь все поля на типы данных и ОЧЕНЬ ВАЖНО! - на длину передаваемых значений. Не допускается в строковом поле передавать больше, скажем, 20 символов. Это очень сильно ограничивает брутфорс для поиска коллизии хэша. Количество фишек должно быть целым положительным числом в определённых допустимых пределах (от 0 до 1000, напримр. Чем меньше диапазон, тем лучше)
    - делаешь хэш по переданным значениям и сравниваешь его с переданным хэшем от клиента. Если не совпадают - юзер подменил количество монет.
    На сервере у тебя должна быть защита от брутфорса: от одного userId, IP-адреса должно приходить не более 1-3 запросов в секунду. Если больше - банить на некоторое время, например, на 1 минуту.

    Это то, что касается систем, где данные передаются ОТ пользователя серверу.

    В твоём же случае - это просто игра.
    И здесь поступают проще.
    Всю логику делают на сервере. Юзер кликнул на монету - передаём серверу инфу: click(userId, x,y)
    И вот тут включается логика сервера: он смотрит что за юзер кликнул, куда кликнул, как часто, разрешено ли ему это делать... Если всё в порядке, то сервер отправляет клиенту - Ок, вот тебе заработанные 10 монет. Клиент отрисовывает монетки, юзер радуется.
    В этом случае полностью исключается подмена юзером количество монет, потому что всё решает сервер. Клиент - это просто терминал для отображения данных и отправки кликов на сервер.
    Ответ написан
    1 комментарий
  • Почему в функции MYSQL при присвоении в переменную значения из таблицы не учитывается условие WHERE?

    @Uncleruc1
    Проблема заключается в том, что в вашей функции условие WHERE \orderid` = 871жестко зафиксировано, и оно всегда будет брать строку с этимorderid, игнорируя переданное значение orderid` в параметр функции.

    Чтобы учитывать переданное значение в параметр функции, необходимо использовать сам параметр orderid вместо фиксированного значения. Вот исправленный код функции:
    DROP FUNCTION IF EXISTS YourFunction;
    DELIMITER $$
    CREATE FUNCTION YourFunction (qty INT, orderid INT) RETURNS TEXT
    
    BEGIN
    DECLARE text_t TEXT;
    SELECT `sum` INTO text_t FROM t_order_price_type WHERE `orderid` = orderid LIMIT 1;
    RETURN text_t;
    END$$
    
    DELIMITER ;


    Однако, в данном виде WHERE \orderid` = orderid` не сработает так, как вы ожидаете, потому что MySQL может спутать поле таблицы с параметром функции. Чтобы избежать этой путаницы, лучше использовать псевдонимы или уникальные имена для параметров. Например:
    DROP FUNCTION IF EXISTS YourFunction;
    DELIMITER $$
    CREATE FUNCTION YourFunction (p_qty INT, p_orderid INT) RETURNS TEXT
    
    BEGIN
    DECLARE text_t TEXT;
    SELECT `sum` INTO text_t FROM t_order_price_type WHERE `orderid` = p_orderid LIMIT 1;
    RETURN text_t;
    END$$
    
    DELIMITER ;

    Здесь параметр функции называется p_orderid, что предотвращает конфликт имен между полем таблицы и параметром функции.
    Ответ написан
    2 комментария
  • Как убрать ненужную всплывающюю подсказку?

    NeoAnderson
    @NeoAnderson
    Оно берёт язык из настроек браузера. Если браузером будет пользоваться человек у которого выставлен интерфейс на английском языке, то будет писаться по английски. Это HTML5
    Ответ написан
    6 комментариев
  • Как синхронизировать проекты между компьютерами?

    @rPman
    syncting или rsync (если подойдет ручное управление) и git (не смешивая их).

    syncting хорошо работает с большими данными и любыми схемами передачи данных (вплоть до источник -> смартфон пользователя offline, смартфон -> целевая машина, и так же обратно, т.е. без интернета)

    git - дисциплинирует ставить 'точки в правильных местах', т.е. вы работаете не абы как а до commit-а, даже если вы один работаете, это дает вам историю изменений, которая может и нужна очень редко, но метко.
    Ответ написан
    Комментировать