• Как выделить в группу повторяющееся выражение?

    vhood
    @vhood
    Не забывайте отмечать решения
    Что-бы одна и та же группа в шаблоне сработала в нескольких местах, должно быть несколько match (что-бы каждое такое место обрабатывалось регуляркой "с нуля", как-бы).
    В регулярках есть разные движки, теоретически тут можно было бы запустить рекурсию, или поработать с динамическими данными в lookahead/lookbehind, но в python, как я понял, не так уж много фич поддерживается.

    Решить в каком-то динамическом виде у меня не получилось. В итоге я скопипастил паттерн некого "хвоста" строки, которая начинается со start (четвертый пример таким образом отпадет) (?:,?\s*(?:(\"[^\"]*\")))? по несколько раз и получил нужный результат (т.е. несколько групп будет в рамках одного match, да и количество групп поддерживается не больше количества скопированного шаблона). Попробовал сократить через DEFINE, но он тоже не поддерживается, видимо. Сделать этот "хвост" именованной группой и использовать ее тоже не получится, т.к. содержимое разное.
    Убрать всякие запятые из match так, как это происходит со start, тоже не удастся - lookahead в python не поддерживает квантификаторы.

    Как-то так: https://regex101.com/r/7eVJFt/4
    Ответ написан
    1 комментарий
  • Функция str_replace() не работает?

    vhood
    @vhood
    Не забывайте отмечать решения
    html_entity_decode()

    https://onlinephp.io/c/9d203 (при работе с этой строкой, учтите, что в строке есть кавычка)
    Ответ написан
    4 комментария
  • Как исправить HEAD detached?

    vhood
    @vhood
    Не забывайте отмечать решения
    Он перешёл на предпоследнюю ветку и не удаляя последнюю, закоммитился
    что еще за "последние" и "предпоследние" ветки, какие-то новые понятия в git?

    Как соединить коммиты и исправить ситуацию?
    в ветке main сделать (на выбор):
    • git reset --hard origin/main, тогда main станет соответстовать origin/main, но коммиты e32d4e8 и 690c2b9 пропадут, но не из истории, так что их можно будет подтянуть: git cherry-pick e32d4e8, git cherry-pick 690c2b9
    • git reset --soft origin/main, посмотреть git status и сделать новые коммиты
    • git rebase origin/main, тогда коммиты e32d4e8 и 690c2b9 начнут применяться заново, начиная с коммита 69805c1 (в ходе применения могут возникать конфликты, а так же у применяемых коммитов будет новый хэш)
    • git rebase -i origin/main (интерактивный ребейз), почти то же самое, как предыдущее, но сначала откроется текстовый редактор (который в git указан как редактор по умолчанию) и в нем можно будет указать как именно делать ребейз, например можно будет не переность коммит 690c2b9 или изменить сообщение коммита
    Ответ написан
    2 комментария
  • Как вставить код с gist в публикацию на Хабре?

    vhood
    @vhood
    Не забывайте отмечать решения
    Нажать / и выбрать "Медиаэлемент", ссылка должна быть на конкретный файл

    https://gist.github.com/Shubin-vadim/a74b3edaa3b73834cf05cfaf3ba6142e#file-functions-mojo
    Ответ написан
    Комментировать
  • Регулярное выражение поиск по группам или нет?

    vhood
    @vhood
    Не забывайте отмечать решения
    preg_match()
    $str = "$status['Совершенно_новое'] = 'Brand_new<br>New'";
    $pattern = "(?<=\$status\[')([а-яА-ЯёЁa-zA-Z]+?.*')([A-za-z]+?.*)(?=')";
    preg_match($patern, $str, $matches);
    
    var_dump($matches);
    // полный match и группы


    Паттерн получше: \$status\['([^']+)'\][^']*'([^']*)'
    https://regex101.com/r/10CLSM/1
    Ответ написан
  • Как подружить html с json?

    vhood
    @vhood
    Не забывайте отмечать решения
    HTML - язык разметки, никакие значения он не меняет
    Ответ написан
    Комментировать
  • Переписать грамотнее и с помощью Laravel реально ли и каким лучше образом?

    vhood
    @vhood
    Не забывайте отмечать решения
    Выводить HTML через echo точно не правильно, изначально PHP полюбили как раз за то, что можно закрыть PHP тег ?> и писать чистый HTML, можно посреди HTML открыть PHP тег <?php и воспользоваться языком, например вывести HTML в цикле (опять же, закрыв тег после начала цикла), или использовать переменную как значение, или выводить HTML по условию.

    В Laravel используется шаблонизатор Blade, но если есть ощущение, что Laravel изучать еще рано, можно через composer поставить какой-нибудь самостоятельный шаблонизатор (искать не сложно) и научиться пользоваться им.

    тут всякие визуальные уточнения страницы; форма, css специфика для страницы
    css стоит писать отдельно и подключать как файл/файлы, для формы будет отдельный шаблон

    тут всякие оперативные реакции на действия в браузере требуемые страницей.
    js тоже стоит писать отдельно и подключать как файл/файлы

    Работа с шаблонами - не самое востребованное знание, скорее очень базовое. Стоит так же изучить:
    • Архитектурный паттерн MVC (Model, View, Controller), т.к. его все популярные фреймворки реализуют и с ним так или иначе придется работать
    • Базы данных и SQL. Обязательно нужно уметь проектировать таблицы и индексы, забирать данные из базы и обновлять их
    • Безопасность, или как правильно писать приложения, что-бы их не взломали SQL инъекциями, XSS атаками и т.д.
    • Маршрутизацию. Можно попробовать найти какой-нибудь php-router на github и изучить работу с ним, внедрить в проект

    Таким образом, приложение будет обрабатывать запрос через некий роутер, посылать его в контроллер (буква C из MVC), контроллер запросит данные в какой-нибудь модели (M), отправит их в шаблон некого шаблонизатора и вернет с его помощью готовый HTML.

    После этого можно будет написать такое же приложение на Laravel, где все это уже есть (и даже больше, разумеется), познакомиться с ActiveRecord (объект, который представляет строку в базе данных) и ORM (для построения запросов). Перед началом стоит прочитать всю документацию, изучить возможности.

    Так же добавлю, что первую работу лично я нашел без знания фреймворков, но хорошее знание языка и баз данных, а так же знания HTML, CSS и базовые знания JS - обязательно. Да и без фронтенда динамичный сайт не сделать, но начать изучение фронтенда лучше всего с изучения чистого javascript, т.к. знание языка важнее и открывает правильную дорогу дальше. А вот на каком этапе изучения останавливаться и куда больше делать упор - решать Вам.
    Ответ написан
    1 комментарий
  • Как посчитать количество строк с group by'ом?

    vhood
    @vhood
    Не забывайте отмечать решения
    SELECT COUNT(1) FROM (
        SELECT class_a.id
        FROM class_a 
        LEFT JOIN `class_p` 
        ON `class_a`.id = `class_p`.p_id
        WHERE class_a.cat_id = 1
        AND (`caption`,`value`) IN (('type','1'), ('type_2','2')) 
        GROUP BY class_a.id 
        HAVING COUNT(DISTINCT caption, value) = 2;
    ) AS tmp
    Ответ написан
  • Как сделать двойной SELECT из одной и той же таблицы?

    vhood
    @vhood
    Не забывайте отмечать решения
    SELECT a.* FROM MY_TABLE a
    INNER JOIN MY_TABLE b
    ON a.COL_1 = b.COL_1 AND a.COL_2 = b.COL_2
    WHERE b.COL_3 = 4107575
    Ответ написан
  • Как правильно сформировать запрос и вывести данные в цикле?

    vhood
    @vhood
    Не забывайте отмечать решения
    Если "в лоб":

    1. Убираем группировку, никаких подгрупп база не выдаст, будет по 1 записи на "уровень"
    - $ref_system = $pdo->prepare("SELECT * FROM `db_ref_system` GROUP BY `rs_type` ORDER BY `id` ASC");
    + $ref_system = $pdo->prepare("SELECT * FROM `db_ref_system` ORDER BY `id` ASC");


    2. Фильтруем итоговый вывод в 3 массива и выводим их
    <?php
    $all = $ref_system->fetchAll();
    $plc = array_filter($all, fn ($fields) => $fields['rs_type'] === 'plc');
    $deposit = array_filter($all, fn ($fields) => $fields['rs_type'] === 'deposit');
    $offer = array_filter($all, fn ($fields) => $fields['rs_type'] === 'offer');
    ?>
    <?php foreach ([$plc, $deposit, $offer] as $level => $data): ?>
      <div class="col-md-4 col-12 mb-lg-0 mb-4">
        <div class="fw-bold h5 mb-3">
          <?= $level + 1 ?>-й уровень
        </div>
        <?php foreach($data as $ref) : ?>
        <div class="mb-4">
          <span class="text-muted fw-semibold"><?=$ref['rs_type']?></span>
          <div>
            <div class="d-flex align-items-center pt-2">
              <div class="progress w-100">
                <div class="progress-bar bg-warning" role="progressbar" style="width: 100%;" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100"></div>
              </div>
              <span class="ms-3 fw-bold text-warning"><?=$ref['rs_percent']?>%</span>
            </div>
          </div>
        </div>
        <?php endforeach; ?>
      </div>
    <?php endforeach; ?>
    Ответ написан
    5 комментариев
  • Как поменять часовой пояс в MYSQL Docker-контейнере?

    vhood
    @vhood
    Не забывайте отмечать решения
    mysql:
      environment:
        MYSQL_DATABASE: marzban
    +   TZ: Europe/Moscow
    Ответ написан
    4 комментария
  • Как поулчить XML выгрузку на Битрикс с вложенными атрибутами?

    vhood
    @vhood
    Не забывайте отмечать решения
    Если это (ссылку взял из комментов в документации) и есть класс \Bitrix\Main\XmlWriter, то с его помощью - никак.

    Он пишет сразу в файл, так что и регуляркой итоговый результат не пройти.

    Можно залезть в него рефлексией, но в программировании это моветон и читабельность кода будет ухудшена.

    Самый оптимальный вариант - наследовать этот класс, изменить несколько его функций и использовать унаследованный класс. Примерно так:
    class AppXmlWriter extends XmlWriter
    {
        private $file = '';
        private $charset = '';
        private $tab = 0;
        private $f = null;
        private $lowercaseTag = false;
        private $errors = array();
    
        // конструктор скопирован, т.к. там все private
        public function __construct(array $params)
        {
            if (isset($params['file']))
            {
                $server = \Bitrix\Main\Application::getInstance()->getContext()->getServer();
                $this->file = $server->getDocumentRoot() . trim($params['file']);
                // create new file
                if (
                    isset($params['create_file']) &&
                    $params['create_file'] === true &&
                    is_writable($this->file)
                    )
                {
                    unlink($this->file);
                }
            }
            if (isset($params['charset']))
            {
                $this->charset = trim($params['charset']);
            }
            else
            {
                $this->charset = SITE_CHARSET;
            }
            if (isset($params['lowercase']) && $params['lowercase'] === true)
            {
                $this->lowercaseTag = true;
            }
            if (isset($params['tab']))
            {
                $this->tab = (int)$params['tab'];
            }
        }
    
        public function prepareAttributes(array $attributes): string
        {
            $result = '';
    
            if (empty($attributes)) {
                return $result;
            }
    
            foreach ($attributes as $key => $value) {
                $result .= sprintf(' %s="%s"', $key, $value);
            }
    
            return $result;
        }
    
        public function writeBeginTag($code, array $attributes = [])
        {
            if (!$this->f) {
                return;
            }
    
            fwrite($this->f, str_repeat("\t", $this->tab) . '<' . $this->prepareTag($code) . $this->prepareAttributes($attributes) . '>' . PHP_EOL);
            $this->tab++;
        }
    
        public function writeFullTag($code, $value, array $attributes = [])
        {
            if (!$this->f) {
                return;
            }
    
            $code = $this->prepareTag($code);
            $codeAttributes = $this->prepareAttributes($attributes);
            fwrite($this->f,
                str_repeat("\t", $this->tab) .
                (
                    trim($value) == ''
                    ? '<' . $code . $codeAttributes . ' />' . PHP_EOL
                    :   '<' . $code . $codeAttributes . '>' .
                    $this->prepareValue($value) .
                    '</' . $code . '>' . PHP_EOL
                )
            );
        }
    }
    Ответ написан
    1 комментарий
  • Как можно изменить выдачу данных из модели?

    vhood
    @vhood
    Не забывайте отмечать решения
    А что сложного?

    Из diff:
    Объекты DateTimeImmutable и DateTime можно сравнивать операторами сравнения.


    class Foo
    {
        public function isGreaterThenNow(): bool
        {
            return $this->someDate > new DateTime();
        }
    }


    чтобы это не выглядело костылем
    тогда проверять лучше не в ActiveRecord, а в спецификации какой-нибудь или ответсвенном объекте
    Ответ написан
  • Какой подход к хранению данных выбрать?

    vhood
    @vhood
    Не забывайте отмечать решения
    Денормализация реляционной базы данных нужна только для оптимизации(и то могут быть другие варианты) или хранения динамического набора полей.
    Оптимизация нужна только тогда, когда есть просадка производительности.

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

    vhood
    @vhood
    Не забывайте отмечать решения
    Если project тоже является проектом, у которого должен быть свой репозиторий, то вложенные проекты нужно добавить в .gitignore
    /server/
    /client/
    /db/

    Если вложенные папки уже отслеживаются гитом, нужно так же удалить их для гита
    git rm -r --cached server
    git rm -r --cached client
    git rm -r --cached db
    
    git add .
    Ответ написан
    Комментировать
  • Yii2 codeception REST API mock external API?

    vhood
    @vhood
    Не забывайте отмечать решения
    Простой вариант (костыли):

    Добавить в функциях, которые ожидают ответ от внешних сервисов, исключения для тестов
    if (YII_ENV_TEST) {
        return true;
    }


    Правильный вариант:

    Зарегистрировать сервис внешних обращений в конфиге, в коде пользоваться только сервисом из контейнера Yii::$app->apiService

    Cоздать загрулшку и зарегистрировать ее в качестве этого сервиса в тестовом конфиге
    # config/test.php
    
    $config =  yii\helpers\ArrayHelper::merge(
        require(__DIR__ . '/web.php'),
        [
            'id' => 'app-tests',
            'components' => [
                'apiService' => [
                    'class' => 'App\Fake\ApiService',
                ],
            ],
        ],
    );
    return $config;

    Тестовый конфиг использовать в настройках модуля Codeception
    # tests/integration.suite.yml
    
    class_name: IntegrationTester
    modules:
        enabled:
          - Asserts
          - Yii2:
                part: [orm, email, fixtures]
                configFile: 'config/test.php'
    Ответ написан
  • Какой вариант структуры файлов моделей в Laravel лучше?

    vhood
    @vhood
    Не забывайте отмечать решения
    Для маленького проекта разницы нет. Можно использовать тот вариант, что быстрее.

    Если хочется знать, есть ли архитектурный паттерн для группировки сущностей - то это DDD (Domain Driven Design). Судя по всему, можно выделать 2 агрегата - Shop и Blog.

    Однако, до изучения темы, лучше выстраивать архитектуру на основе известных принципов программирования.
    Ответ написан
    2 комментария
  • Как переместить скопировать удаленный репозиторий в другой удаленный репозиторий?

    vhood
    @vhood
    Не забывайте отмечать решения
    1. Клонируешь проект из исходного репозитория

    git clone <ссылка на старый>

    2. Переходишь в склонированный репозиторий и добавляешь новый удаленный репозиторий

    git remote add copy <ссылка на новый>

    3, Пушишь коммиты в новый репозиторий (выше в команде я назвал его copy)

    git push --all copy
    Ответ написан
    Комментировать
  • Как обвести текст по контуру при переносе на две строки?

    vhood
    @vhood
    Не забывайте отмечать решения
    На мой взгляд, проще и красивее сделать на всю ширину660ba7a877a5a703431304.png

    Но если нужно получить ожидаемое, то вариант - явно разделить строки (например, в инспекторе я нажал shift+enter) и указать для ссылок white-space: pre-line. Соответственно, white-space можно менять в медиа запросе.

    <a href="#">Детское игровое и спортивное
    оборудование</a>

    .goods-cat__labels > a {
        white-space: pre-line;
    }

    660d20186dba8612507388.png
    Ответ написан
    1 комментарий