• 1С-Битрикс. Как массово и достаточно быстро удалить все разделы в инфоблоке?

    winer
    @winer
    занимаюсь разработкой сайтов на 1c-bitrix
    При большом количестве разделов (30к+), Bitrix начинает вставлять палки в колеса как разработчику, так и пользователю, который будет работать с такими ИБ.
    - Списки элементов ИБ будут безбожно тормозить в интерфейсе. На каждом хите будет добавляться фильтр по разделу.
    - Редактировать их становится очень затруднительно, опять же из за долгой загрузки интерфейса и большого времени изменения.

    Всё это из за того что разделы это NESTED SETS деревья. При добавлении/удалении раздела происходит вычисление LEFT_MARGIN и RIGHT_MARGIN для каждого раздела во всем инфоблоке.

    Для добавления и обновления (CIBlockSection::Add, CIBlockSection::Update) есть параметр метода $bResort, который позволяет отключить этот перерасчёт в момент их выполнения.
    Только после этого ОБЯЗАТЕЛЬНО надо выполнять CIBlockSection::Resort.

    Это можно использовать при большом количестве операций Update и Add. Сначала выполняете все операции Update и Add с $bResort=false, а после них CIBlockSection::Resort

    НО!! К сожалению, такой параметр для CIBlockSection::Delete не доступен. И вот тут начинается жесть.
    Каждый вызов CIBlockSection::Delete, это:
    • пересчет границ NESTED SETS,
    • CIblockElement::GetList (поиск вложенных элементов)
    • CIblockElement::Delete (если в разделе были элементы),
    • Запрос к таблице которая хранит множественные привязки элемента к разделам (поиск значений и их удаление)
    • CIBlockSection::GetList (поиск вложенных разделов)
    • CIBlockSection::Delete (удаление вложенных разделов)
    • Переиндексирование поиска
    • Запросы к UF_* полям раздела (поиск значений и их удаление)
    • При заполненных SEO полях, запросы к таблицам которые их хранят (поиск значений и их удаление)
    • При расширенном управлении правами это еще запросы к таблицам которые хранят эти настройки (поиск значений и их удаление)


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

    Нельзя быстро удалить разделы стандартным API без написания своих запросов к БД которые проделают всё что описано выше. В идеале надо взять код стандартного CIBlockSection::Delete, внимательно его изучить и написать свой метод который будет с помощью прямых запросов делать тоже самое, но оптимально.

    Если же вопрос стоит в том чтобы удалить эти разделы за ЛЮБОЕ количество времени, тогда можно написать страничку с пошаговым удалением разделов, через ajax запросы. Причем надо учитывать, что вначале разделы будут удаляться ОЧЕНЬ медленно и ajax запрос может отвалиться по таймауту, поэтому надо будет за один шаг удалять пару разделов. А ближе к границе в 10к разделов, за один шаг можно будет удалять уже большее количество.
    Ответ написан
    Комментировать
  • Навигация по pgAdmin 4, просмотр записей таблиц?

    @mezhuev
    Системный администратор
    Через контекстное меню таблицы:
    4038b3f76392a2db5481262932949bcf.png
    Ответ написан
    5 комментариев
  • Можно ли написать функцию создающую DOM элементы?

    bootd
    @bootd
    Гугли и ты откроешь врата знаний!
    // tagName - Имя тега
    // props - объект с свойствами DOM элемента
    // children - массив с DOM элементами
    function createElement (tagName, props = {}, children = []) {
      const newDOMElement = document.createElement(tagName);
      
      if (props) {
        for (const prop in props) {
          if (Object.prototype.hasOwnProperty.call(props, prop)) {
            newDOMElement[prop] = props[prop];
          }
        }
      }
      
      if (children.length) {
        children.forEach(child => {
          newDOMElement.append(child);
        });
      }
      
      return newDOMElement;
    }
    
    const body = document.body;
    
    // Создаём новый DOM узел
    const newDOM = createElement('div', null, [
      createElement('h1', null, [
        'Заголовок страницы'
      ]),
      createElement('p', null, [
        'Привет, Мир!'
      ]),
      createElement('button', {
        onclick: () => {
          alert('бабах');
        }
      }, [
        'Кликни меня'
      ])
    ]);
    
    // Вставляем в body новый DOM узел
    body.append(newDOM);


    Код по сути написал для примера, много особенностей работы с DOM не учтено, но принцип я показал
    Ответ написан
    Комментировать
  • Нужно ли делать валидацию формы на фронте и бэке одновременно?

    yarkov
    @yarkov Куратор тега JavaScript
    Помог ответ? Отметь решением.
    какой из этих путей «джедайский»?

    Джедайский путь только один и он такой: и на фронте на JS и на бэке на PHP.
    Любые данные, которые могут прилететь на бэкенд, надо по-умолчанию считать опасными и обязательно валидировать.
    Ответ написан
    Комментировать
  • Что возвращает нам fetch и как можно им правильней пользоваться?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Из fetch вы получаете Promise.
    При разрешении этого промиса (через .then или await) вы получаете объект Response, из которого можете достать данные любым удобным для вас методом.
    Ответ написан
    Комментировать
  • Ошибка при установке bootstrap в Laravel, как исправить?

    iMedved2009
    @iMedved2009
    Не люблю людей
    Дык он запустил сервер для отладки и ждет когда вы начнете отлаживать.
    Ответ написан
    2 комментария
  • Зачем нужна инкапсуляция в ООП?

    sergey-gornostaev
    @sergey-gornostaev
    Седой и строгий
    Попробуйте учебники читать, а не видео смотреть. Все принципы ООП, сам ООП и другие парадигмы, а также шаблоны проектирования существуют для управления сложностью. Понять всё это проще всего тогда, когда столкнулся с десятилетнем легаси в проекте с большой командной.
    Ответ написан
    Комментировать
  • Зачем нужна инкапсуляция в ООП?

    DollyPapper
    @DollyPapper
    Инкапсуляция вообще является (ИМХО) главным принципом из 4. Инкапсуляция + абстракция. Вы не поняли её основную идею. Инкапсуляция это объдинение в одной сущности данных (не обязательно в общем-то) и действий которая эта сущность может предоставить. Инкапсуляция + абстракция представляю собой в общем более общий принцип - сокрытие информации/сложности, и один без другого не сильно то полезен. Не путать с модификаторами доступа (public, private и тд). Этот принцип идет скрозь всю историю развития языков программирования и собственно является главной движущей силой их развития. Вот пример из реальной жизни: есть у вас микроволновка. Она имеет +- 2 нопки: выставить время, выставить мощность. Это интерфейс микроволновки, который доступен конечному пользователю. Всё что вам нужно знать, чтобы приготовить себе похавать - 1)на какой мощности это хавать, нужно готовить 2) сколько это нужно делать по времени. При этом очевидно внутри микроволновки происходит та самая сложность, микросхемы гоняют электрический ток, магнетрон изучает электромагнитные волны, всякая разная физика происходит и вот это вот всё. Итого: вся эти физика и электротехника инкапсулирована в объект микроволновки (инкапсулирована так, что мы не можем добраться до её внутреннего устройства, это важно. Т.е. мы не можем сами соединить проводки, поменять электрическую цель, чтобы себе похавать сделать, разработчик этой электропечки не дал нам даже потенциальную возможность это сделать легально. Можно конечно разобрать устройство и проделать все эти манипуляции, но это уже это на совести того самоделкина, кто это делает). Итого: мы имеем интерфейс из двух кнопок и получаем от обьекта микроволновки услугу - приготовить пожрать. Как там внутри это реализовано, нам не важно. Это и есть инкапсуляция + абстракция = сокрытие информации/сложности.
    Более программистский пример: есть такая структура данных - Стек. Хотя по факту это не структура данных, а абстрактный тип данных. Советую этот термин загуглить, это важная составляющая в понимании ООП.
    Представим, что стек это такой обьект который предоставляет услуги, по типу как мы представляли себе обьект микроволновки. Что нам нужно знать про стек, чтобы им пользоваться? Публичный интерфейс. Т.е. есть класс Stack с публичными методами push(), pop(), viewTopStack() (посмотреть первый элемент стека, без его удаление из самого стека). Всё, можно пользоваться. Как он внутри эти элементы хранит, простой ли это массив, или связный список, на сколько эффективно он там внутри работает - нам не важно. Это важно тому, кто предоставил нам в пользование данный класс. Мы знаем, что вызвав viewTopStack мы посмотрим первый элемент стека, вызвав push - положим что-то в стек, вызвав pop получим первый элемент, удалив его из стека (по аналогии: мы знаем что чтобы притоговить пожрать, нужно выставить в микроволновке время и мощность, на выходе получив наше адово хрючево). Если подытожить - инкапсуляци + абстракция, (еще раз настою на том, что порознь их нельзя рассматривать, это две тесно связанные концепции которые имеют практический смысл только в синергии) это механизм борьбы со сложностью, не только в программировании, вообще везде, в любой человеческой деятельности. В этом их смысл. Если ваши абстракции плохие -> ваш код сложный -> ваш код плохой (говнокодом его еще называют в сообществе программистов).
    Почитать на эту тему можно следующее: Р.Мартин - Чистая архитектура (начать с глав про SOLID прицнипы), С.Макконел - Совершенный код (главу про классы обязательно, остальное желательно (очень желательно)), там в общем-то вам расскажут то что я вам сейчас рассказал, только более подробно, по больше примеров и дадут обоснование сложности, назвав борьбу с ней - Главным техническим императивом. Шлифануть это книгой банды четырех. Сами паттерны не обязательно начинать учить (да и рано вам еще), но вот введение и часть про программирование на основе интерфейса, а не реализации - самое оно, это дополнит картину.

    UPD: тот факт, что мы в классе стек собрали его функционал (функции pop,push,...) обьединенные одной общей темой и есть факт инкапсуляции.
    Ответ написан
    Комментировать
  • Поможете исправить несколько багов в верстке?

    @Pavstyuk
    Первое что бросилось в глаза. Вы жестко ограничиваете ширину контэйнера:
    .container {
      margin: 0 auto;
      width: 1150px;
    }

    Попробуйте так, должно стать гораздо лучше:
    .container {
      margin: 0 auto;
      max-width: 1150px;
      width: 100%;
    }


    Далее вместо:
    .blog_wrapper {
      display: flex;
    }

    Добавьте перенос:
    .blog_wrapper {
      display: flex;
      flex-wrap: wrap;
    }

    Это же касается всех остальных блоков, где вы используете display: flex.
    Ответ написан
    2 комментария
  • Правильно ли реализован класс для работы с базой данных по принципу SOLID?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Во-первых, это никакой не DatabaseManager , а CRUDManager. Работа с БД далеко не ограничивается этими 4 примитивными функциями.

    Отсюда мы делаем логичный вывод, что соединение с БД никаким местом не должно создаваться в конструкторе менеджера крудов. А должно точно так же передаваться в него в качестве зависимости. Это может быть либо ванильная ПДО, либо инстанс реального MySQLDatabase (но поскольку мы пока не знаем, как он должен выглядеть, то лучше остановиться на PDO).

    Сам по себе DatabaseManager выглядит избыточным. Непонятно, зачем он нужен, если любой потребитель DatabaseManager-а может просто написать
    public function __construct(CRUDInterface $crud) {
    }

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

    В-четвёртых, хоть это и не относится напрямую к теме SOLID, но для меня является очень важным: собственно, реализация методов CRUD-а. Что в них передаётся? Откуда берутся названия таблиц, полей? Передаются в параметрах методов? Это прямая дорога к SQL инъекции, не говоря уже о нарушении инкапсуляции. Поэтому, отвечая на вопрос "Как вы реализуете работу с базой данных", лично я всё больше в последнее время от развесистых ORM-ов склоняюсь к простым TableGateway-ам. Да, кода писать больше, но он строже и понятнее. И не встаёт колом в нестандартных ситуациях. Тем более что приведённый пример кода как раз очень и похож на этот паттерн. То есть
    abstract class MysqlTableGateway implements CrudInterface
    {
        protected $db;
        protected $table;
        protected $fields;
        protected $primary = 'id';
    
        public function __construct(\PDO $db)
        {
            $this->db = $db;
        }
        public function read($id): ?array
        {
            $stmt = $this->db->prepare("SELECT * FROM `$this->table` WHERE `$this->primary`=?");
            $stmt->execute([$id]);
            return $stmt->fetch();
        }
         // ну и так далее
    }

    И дальше уже классы по работе с отдельными табличками наследовать от него,
    final class UserGateway extends MysqlTableGateway {
        protected $table = 'users';
        protected $fields = ['email', 'password','phone'];
    }

    Соответственно, если мы захотим перейти с мускуля на какой-нибудь редис с джейсоном внутре, то надо будет создать новый абстрактный класс с тем же интерфейсом, и от него отнаследовать реализации. Соответственно, в интерфейсе надо нормально прописать входные и выходные параметры:
    interface CRUDInterface {
        public function create(array $data):int;
        public function read(int $id):?array;
        public function update(array $data);
        public function delete(int $id);
    }

    Другое дело, что в реальности такой шалтай-болтай будет сделать довольно сложно, поскольку классы для работы с отдельными таблицами будут расширяться запросами, специфичными для данной таблицы - то есть все их придется дописывать во все драйверы. То есть в реальности с D будут проблемы. Но чисто с теоретической точки зрения примерно вот так оно будет выглядеть.
    Ответ написан
    4 комментария
  • Не получается обработать простой webhook, как обработать?

    @SevenShots Автор вопроса
    Всё. Разобрался. Оказывается я не поставил слеш в конце URL)))
    Ответ написан
    Комментировать
  • Как правильно написать классы БЭМ для кнопок?

    Get-Web
    @Get-Web Куратор тега CSS
    Front-End Developer
    Блок_модификатор_значение

    button_theme_ghost
    button_size_small

    <button class="button button_theme_ghost button_size_small">
    Ответ написан
    3 комментария
  • Как показать подразделы в компоненте bitrix:news?

    scottparker
    @scottparker
    "SEF_URL_TEMPLATES" => array(
    "news" => "",
    "section" => "#SECTION_CODE#/",
    "detail" => "#SECTION_CODE_PATH#/#ELEMENT_CODE#/",
    )

    в параметрах подключения компонента должно быть примерно так, аналогичное советую прописать и в настройках инфоблока, что ссылки в том же поиске корректно формировались
    Ответ написан
    3 комментария
  • Можно ли ограничить время жизни данных при сохранеии в localstorage?

    chlp
    @chlp
    фулстек
    Нативно – нет.
    Можно самому, например, так:
    var limit = 24 * 3600 * 1000; // 24 часа
    var localStorageInitTime = localStorage.getItem('localStorageInitTime');
    if (localStorageInitTime === null) {
        localStorage.setItem('localStorageInitTime', +new Date());
    } else if(+new Date() - localStorageInitTime > limit)
        localStorage.clear();
        localStorage.setItem('localStorageInitTime', +new Date());
    }
    Ответ написан
    Комментировать
  • Как избежать в Figma прилипания элементов к фрейму?

    mixail_fet
    @mixail_fet
    Дизайнер веб-интерфейсов
    Все слои которые находятся внутри Фрейма, автоматически к нему привязываются. Внутри Фрейма, для каждого объекта можно задать позицию, в которой он будет находится при изменении масштаба. Чтобы при деформации Фрейма, объекты внутри не меняли свои размеры, нужно задать слою или группе слоев позицию.

    5ba0d6fc56a85186964930.jpeg

    На картинке задана позицию Left - Top, это означает что объект всегда будет привязан к верхнему левому углу.
    Ответ написан
    7 комментариев
  • Стоит ли стажироваться на php разработчика, если у них cms Битрикс?

    Mikhail_01
    @Mikhail_01
    администратор Битрикс
    Битрикс это тоже фреймворк.
    Весьма востребованный, коммерческий.
    Тем кто не знаком с Битрикс24.... на нем работают 7лямов компаний по всему миру.
    Да это в основном облако.... но коробочная версия Б24 работает также на всех языках и странах.

    вакансии на НН полистайте
    Ответ написан
    Комментировать
  • Jquery события при checked?

    karjan
    @karjan Автор вопроса
    Вот решение
    $( "input:checkbox" ).on("change", function() {
            $('.reg').slideToggle();
        });
    Ответ написан
  • Калькулятор с RADIOBUTTON. Значение radiobutton отображается alert, но к сумме не подтягивается/?

    alekseyHunter
    @alekseyHunter
    Android developer
    1) Названия на транслите - плохой подход
    2) Id должен быть уникален

    document.querySelector('[type="radio"]:checked').value


    P.S. Все у вас работает
    Ответ написан
    1 комментарий