• Как прочитать данные из двух таблиц одновременно?

    ValeriuCutebov
    @ValeriuCutebov
    Для того чтобы получить данные из двух таблиц, вам необходимо сделать JOIN запрос к базе данных, объединяя таблицу материалов с таблицей категорий. Пример такого запроса может выглядеть так:

    SELECT f.*, c.category_name 
    FROM freeroll f 
    JOIN category c ON f.category_id = c.id 
    ORDER BY f.id

    В этом запросе мы объединяем таблицы freeroll и category, используя условие ON f.category_id = c.id, и выбираем все столбцы из таблицы freeroll (*) и столбец category_name из таблицы category. Этот запрос вернет результат, который содержит данные из обеих таблиц, а также связанные данные из таблицы category для каждого материала.

    Чтобы реализовать этот запрос в методе read() вашей модели Freeroll, вам необходимо изменить запрос в методе read() на:
    $query = "SELECT f.*, c.category_name 
              FROM " . $this->table_name . " f 
              JOIN category c ON f.category_id = c.id 
              ORDER BY f.id";

    Затем, в цикле while, вы можете добавить значение category_name к массиву $freeroll_item:
    $freeroll_item = array(
        "id" => $id,
        "name_turnament" => $name_turnament,
        "prize" => $prize,
        "password" => $password,
        "data" => $data,
        "time" => $time,
        "category_id" => $category_id,
        "category_name" => $category_name,
        "buyin" => $buyin,
        "buyin_symbol" => html_entity_decode($buyin_symbol),
        "prize_symbol" => html_entity_decode($prize_symbol)
    );

    Здесь мы добавляем значение category_name к массиву $freeroll_item, которое мы получили из таблицы category с помощью JOIN запроса.

    Далее, в методе read.php вы можете вызвать метод read() вашей модели Category, чтобы получить все записи из таблицы категорий, и сохранить результаты в массив $category_arr. Это можно сделать следующим образом:
    $category = new Category($db);
    $category_stmt = $category->read();
    $category_num = $category_stmt->rowCount();
    
    $category_arr = array();
    while ($category_row = $category_stmt->fetch(PDO::FETCH_ASSOC)) {
        extract($category_row);
        $category_item = array(
            "id" => $id,
            "category_name" => $category_name
        );
        array_push($category_arr, $category_item);
    }

    Затем, внутри цикла while для каждого материала в $freeroll_arr, вы можете перебрать массив $category_arr, чтобы найти категорию с нужным id, и добавить ее значение к массиву $freeroll_item:
    while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
        extract($row);
    
        $freeroll_item = array(
            "id" => $id,
            "name_turnament" => $name_turnament,
            "prize" => $prize,
            "password" => $password,
            "data" => $data,
            "time" => $time,
            "category_id" => $category_id,
            "buyin" => $buyin,
            "buyin_symbol" => html_entity_decode($buyin_symbol),
            "prize_symbol" => html_entity_decode($prize_symbol)
    );
    
    // Поиск категории с нужным id в массиве $category_arr
    foreach ($category_arr as $category_item) {
        if ($category_item['id'] == $category_id) {
            $freeroll_item['category_name'] = $category_item['category_name'];
            break;
        }
    }
    
    array_push($freeroll_arr["freeroll"], $freeroll_item);
    }

    Здесь мы ищем категорию с нужным id в массиве $category_arr, и если находим, добавляем значение category_name к массиву $freeroll_item.

    Теперь ваш метод read() будет возвращать все записи из таблицы freeroll, включая название категории для каждого материала.
    Ответ написан
    1 комментарий
  • Как в REDUX QUERY получить response?

    ValeriuCutebov
    @ValeriuCutebov
    Для того, чтобы получить ответ (response) в Redux Query, можно использовать обработчик onSuccess. В onSuccess вы можете обработать ответ и выполнить действия с полученными данными, такими как сохранение в Redux Store или отображение на странице.

    В вашем случае, вы можете изменить ваше определение мутации, чтобы добавить обработчик onSuccess, который будет выводить ответ в консоль.

    Попробуйте данный код:
    export const usersApi = createApi({
      reducerPath: 'usersApi',
      baseQuery: fetchBaseQuery({ baseUrl: 'https://localhost:7777/' }),
      endpoints: (builder) => ({
        registerUser: builder.mutation<{}, IUser>({
          query: (user) => ({
            url: '/register',
            method: 'POST',
            body: user,
          }),
          onSuccess: (response) => {
            console.log(response.data);
          },
        }),
      }),
    });

    В этом примере добавил обработчик onSuccess к определению мутации. Обработчик получает аргументом ответ (response) от API, и выводит его содержимое в консоль с помощью метода console.log.

    После того, как мутация выполнится, вы сможете увидеть ответ в консоли браузера. Обычно ответ от API содержится в свойстве data объекта response, как показано в примере выше (response.data).
    Ответ написан
    Комментировать
  • Как присвоить стиль через JS?

    ValeriuCutebov
    @ValeriuCutebov
    Проблема заключается в том, что скрипт выполняется раньше, чем элементы страницы загружены и доступны для манипуляций. Попробуйте обернуть ваш скрипт в обработчик события DOMContentLoaded, чтобы выполнение скрипта началось только после полной загрузки документа:

    document.addEventListener('DOMContentLoaded', function() {
      var divContent = document.querySelector('.crm-kanban-item-repeated').closest('.crm-kanban-item')
      var StyleContents = divContent.style.background = '#000'
      console.log(StyleContents)
    });

    Также убедитесь, что элемент с классом crm-kanban-item-repeated существует на странице в момент выполнения скрипта, иначе querySelector вернет null.
    Ответ написан
    Комментировать
  • Как сделать возможность выбора диапазона даты?

    ValeriuCutebov
    @ValeriuCutebov
    Решение с использованием HTML5, CSS3, React JS:
    <div id="calendar"></div>
    
    <script src='https://npmcdn.com/react@15.3.0/dist/react.min.js'></script>
    <script src='https://npmcdn.com/react-dom@15.3.0/dist/react-dom.min.js'></script>
    <script src='https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.14.1/moment-with-locales.min.js'></script>
    
    <script>
    'use strict';
    
    const Heading = ({ date, changeMonth, resetDate }) => /*#__PURE__*/
    React.createElement("nav", { className: "calendar--nav" }, /*#__PURE__*/
    React.createElement("a", { onClick: () => changeMonth(date.month() - 1) }, "\u2039"), /*#__PURE__*/
    React.createElement("h1", { onClick: () => resetDate() }, date.format('MMMM'), " ", /*#__PURE__*/React.createElement("small", null, date.format('YYYY'))), /*#__PURE__*/
    React.createElement("a", { onClick: () => changeMonth(date.month() + 1) }, "\u203A"));
    
    
    
    const Day = ({ currentDate, date, startDate, endDate, onClick }) => {
      let className = [];
    
      if (moment().isSame(date, 'day')) {
        className.push('active');
      }
    
      if (date.isSame(startDate, 'day')) {
        className.push('start');
      }
    
      if (date.isBetween(startDate, endDate, 'day')) {
        className.push('between');
      }
    
      if (date.isSame(endDate, 'day')) {
        className.push('end');
      }
    
      if (!date.isSame(currentDate, 'month')) {
        className.push('muted');
      }
    
      return /*#__PURE__*/(
        React.createElement("span", { onClick: () => onClick(date), currentDate: date, className: className.join(' ') }, date.date()));
    
    };
    
    const Days = ({ date, startDate, endDate, onClick }) => {
      const thisDate = moment(date);
      const daysInMonth = moment(date).daysInMonth();
      const firstDayDate = moment(date).startOf('month');
      const previousMonth = moment(date).subtract(1, 'month');
      const previousMonthDays = previousMonth.daysInMonth();
      const nextsMonth = moment(date).add(1, 'month');
      let days = [];
      let labels = [];
    
      for (let i = 1; i <= 7; i++) {
        labels.push( /*#__PURE__*/React.createElement("span", { className: "label" }, moment().day(i).format('ddd')));
      }
    
      for (let i = firstDayDate.day(); i > 1; i--) {
        previousMonth.date(previousMonthDays - i + 2);
    
        days.push( /*#__PURE__*/
        React.createElement(Day, { key: moment(previousMonth).format('DD MM YYYY'), onClick: date => onClick(date), currentDate: date, date: moment(previousMonth), startDate: startDate, endDate: endDate }));
    
      }
    
      for (let i = 1; i <= daysInMonth; i++) {
        thisDate.date(i);
    
        days.push( /*#__PURE__*/
        React.createElement(Day, { key: moment(thisDate).format('DD MM YYYY'), onClick: date => onClick(date), currentDate: date, date: moment(thisDate), startDate: startDate, endDate: endDate }));
    
      }
    
      const daysCount = days.length;
      for (let i = 1; i <= 42 - daysCount; i++) {
        nextsMonth.date(i);
        days.push( /*#__PURE__*/
        React.createElement(Day, { key: moment(nextsMonth).format('DD MM YYYY'), onClick: date => onClick(date), currentDate: date, date: moment(nextsMonth), startDate: startDate, endDate: endDate }));
    
      }
    
      return /*#__PURE__*/(
        React.createElement("nav", { className: "calendar--days" },
        labels.concat(),
        days.concat()));
    
    
    };
    
    class Calendar extends React.Component {
      constructor(props) {
        super(props);
    
        this.state = {
          date: moment(),
          startDate: moment().subtract(5, 'day'),
          endDate: moment().add(3, 'day') };
    
      }
    
      resetDate() {
        this.setState({
          date: moment() });
    
      }
    
      changeMonth(month) {
        const { date } = this.state;
    
        date.month(month);
    
        this.setState(
        date);
    
      }
    
      changeDate(date) {
        let { startDate, endDate } = this.state;
    
        if (startDate === null || date.isBefore(startDate, 'day') || !startDate.isSame(endDate, 'day')) {
          startDate = moment(date);
          endDate = moment(date);
        } else if (date.isSame(startDate, 'day') && date.isSame(endDate, 'day')) {
          startDate = null;
          endDate = null;
        } else if (date.isAfter(startDate, 'day')) {
          endDate = moment(date);
        }
    
        this.setState({
          startDate,
          endDate });
    
      }
    
      render() {
        const { date, startDate, endDate } = this.state;
    
        return /*#__PURE__*/(
          React.createElement("div", { className: "calendar" }, /*#__PURE__*/
          React.createElement(Heading, { date: date, changeMonth: month => this.changeMonth(month), resetDate: () => this.resetDate() }), /*#__PURE__*/
    
          React.createElement(Days, { onClick: date => this.changeDate(date), date: date, startDate: startDate, endDate: endDate })));
    
    
      }}
    
    
    ReactDOM.render( /*#__PURE__*/
    React.createElement(Calendar, null),
    document.getElementById('calendar'));
    </script>
    
    
    <style>
    body {
      font-family: "Roboto", sans-serif;
      background-color: #f8f7fa;
      color: #333;
    }
    
    .calendar {
      position: absolute;
      top: 50%;
      left: 50%;
      margin-top: -225px;
      margin-left: -195px;
      width: 360px;
      padding: 15px;
      box-shadow: 1px 1px 20px 0 rgba(0, 0, 0, 0.4);
      border-radius: 12px;
      overflow: hidden;
    }
    .calendar--nav {
      margin: -15px -15px 15px;
      padding: 0 15px;
      background-color: #b670f4;
      color: #fff;
      height: 70px;
      position: relative;
    }
    .calendar--nav a {
      position: absolute;
      cursor: pointer;
      left: 10px;
      font-size: 32px;
      line-height: 1;
      top: 16px;
      width: 30px;
      text-align: center;
      display: inline-block;
      color: rgba(255, 255, 255, 0.4);
      -webkit-user-select: none;
         -moz-user-select: none;
          -ms-user-select: none;
              user-select: none;
    }
    .calendar--nav a:hover {
      color: #fff;
    }
    .calendar--nav a:last-child {
      left: auto;
      right: 10px;
    }
    .calendar--nav h1 {
      margin: 0;
      position: absolute;
      left: 40px;
      right: 40px;
      text-align: center;
      cursor: pointer;
      font-weight: 400;
      font-size: 30px;
      line-height: 66px;
      -webkit-user-select: none;
         -moz-user-select: none;
          -ms-user-select: none;
              user-select: none;
    }
    .calendar--nav small {
      font-weight: 300;
      font-size: 60%;
    }
    .calendar--days {
      font-size: 0;
    }
    .calendar--days span {
      width: 14.28571%;
      display: inline-block;
      text-align: center;
      -webkit-user-select: none;
         -moz-user-select: none;
          -ms-user-select: none;
              user-select: none;
      cursor: pointer;
      margin: 8px 0;
      line-height: 34px;
      position: relative;
      font-size: 16px;
    }
    .calendar--days span.label {
      text-transform: uppercase;
      font-weight: 700;
      color: rgba(0, 0, 0, 0.3);
      font-size: 14px;
      cursor: initial;
    }
    .calendar--days span.active {
      font-weight: 700;
      background-color: rgba(182, 112, 244, 0.05);
      border-radius: 12px;
    }
    .calendar--days span.muted {
      color: rgba(0, 0, 0, 0.3);
    }
    .calendar--days span.between {
      border-radius: 0;
    }
    .calendar--days span.start, .calendar--days span.between, .calendar--days span.end {
      background-color: #b670f4;
      color: #fff;
    }
    .calendar--days span.start {
      border-radius: 12px 0 0 12px;
    }
    .calendar--days span.end {
      border-radius: 0 12px 12px 0;
    }
    .calendar--days span.start.end {
      border-radius: 12px;
    }
    .calendar--days span.between:nth-child(7n):after, .calendar--days span.start:nth-child(7n):after {
      content: "";
      position: absolute;
      top: 0;
      bottom: 0;
      left: 100%;
      background-color: #b670f4;
      width: 20px;
    }
    .calendar--days span.between:nth-child(7n+1):after, .calendar--days span.end:nth-child(7n+1):after {
      content: "";
      position: absolute;
      top: 0;
      bottom: 0;
      right: 100%;
      background-color: #b670f4;
      width: 20px;
    }
    .calendar--days span.start.end:after {
      display: none;
    }
    </style>
    Ответ написан
  • Аналог caniuse для эмодзи?

    ValeriuCutebov
    @ValeriuCutebov
    Да, есть подобный сервис для эмодзи, называется Emojipedia. На этом сайте вы можете найти информацию о том, какие эмодзи поддерживаются на разных операционных системах, таких как iOS, Android, Windows и т. д. Вы также можете узнать, как выглядят эмодзи на разных устройствах и как они могут отображаться на разных браузерах. Кроме того, на сайте Emojipedia можно найти описание каждого эмодзи и его историю.
    Ответ написан
    Комментировать
  • Как добавить/удалить class после прокрутки?

    ValeriuCutebov
    @ValeriuCutebov
    Привет! Для добавления класса scroll-up при прокрутке вверх можно сохранять предыдущее значение scrollTop и сравнивать его с текущим значением при каждом событии прокрутки. Если текущее значение меньше предыдущего, то добавляем класс scroll-up, иначе удаляем его. Для удаления класса scroll-up при достижении header__section-info можно получить координаты этого элемента и удалить класс, если текущее значение scrollTop больше или равно его координатам.

    Вот пример кода:
    document.addEventListener('DOMContentLoaded', function () {
      'use strict';
    
      var prevScrollpos = window.pageYOffset;
      var sectionInfo = document.querySelector('.header__section-info').getBoundingClientRect().top + window.pageYOffset;
      var headerOneELement = document.querySelector('.header__section-navbar');
    
      window.addEventListener('scroll', function () {
        var currentScrollpos = window.pageYOffset;
    
        // fixedHeader on scroll
        function fixedHeader() {
          if (currentScrollpos > sectionInfo) {
            headerOneELement.classList.add('fix');
            headerOneELement.classList.add('scroll-up');
            document.querySelector('.header').style.marginBottom = headerOneELement.offsetHeight + 'px';
    
            if (currentScrollpos < prevScrollpos) {
              headerOneELement.classList.remove('scroll-up');
            }
          } else {
            headerOneELement.classList.remove('fix');
            headerOneELement.classList.remove('scroll-up');
            document.querySelector('.header').style.marginBottom = '0';
          }
          prevScrollpos = currentScrollpos;
        }
    
        fixedHeader();
      });
    });

    Обрати внимание, что я сохраняю координаты header__section-info в переменной sectionInfo с учетом текущего значения scrollTop. Я также инициализирую переменную prevScrollpos вне функции обработчика события прокрутки, чтобы она была доступна внутри обработчика и сохраняла значение scrollTop предыдущего события.
    Ответ написан
    8 комментариев
  • Скрипт работает не так javascript, можно ли что то с эти сделать?

    ValeriuCutebov
    @ValeriuCutebov
    Для того, чтобы скрипт работал не только один раз, вам нужно добавить функцию, которая будет удалять все созданные элементы после их анимации. Для этого вы можете использовать метод .empty() или .remove() для удаления всех созданных элементов.

    Вот как может выглядеть обновленный код:
    <script>
        let id;
        let j = 1;
    
        $('.main-i').hover(function() {
            let a = $('.main-i').offset();
            for (let i = 1; i <= 9; i++) {
                $('.pc-spans').append('<span data-class="span-i" data-id=' + i + ' class="i-am-os">text</span>');
                $('.i-am-os[data-id="' + i + '"]').offset({ top: a.top + i * 13, left: a.left + i ** 2 });
            }
            $('.pc-spans').append('<span data-class="span-i" data-id=' + 10 + ' class="i-am-os">text</span>');
            $('.i-am-os[data-id="' + 10 + '"]').offset({ top: a.top + 10 * 13, left: a.left + 50 + 10 ** 2 });
            for (let i = 11; i <= 22; i++) {
                $('.pc-spans').append('<span data-class="span-i" data-id=' + i + ' class="i-am-os">text</span>');
                $('.i-am-os[data-id="' + i + '"]').offset({ top: a.top - (i - 20) * 13, left: a.left - (i - 22) ** 2 + 360 });
            }
        }, function() {
            id = setInterval(function() {
                $('.i-am-os[data-id="' + j + '"]').animate({
                    opacity: '0',
                    color: '#00000000'
                }, 100, function() {
                    $(this).remove();
                });
                if (j > 22) {
                    clearInterval(id);
                    $('.pc-spans').empty(); // Remove all elements created on hover
                } else {
                    j++;
                }
            }, 100);
        });
    
    </script>

    Также я заметил опечатку в анимации - в свойстве color вы написали olor, я исправил это в обновленном коде.
    Ответ написан
  • Как получить одно из значений ответа на запрос?

    ValeriuCutebov
    @ValeriuCutebov
    Чтобы получить значение transaction_status из ответа на запрос, вам нужно сначала декодировать JSON-строку в массив PHP. Это можно сделать с помощью функции json_decode:

    $response = '{"status":"success","1":{"transaction":"8025400","email":"Не указана","amount":"21.38","currency":"RUB","currency_amount":"20.00","comission_percent":"6.90","comission_fixed":"0.00","amount_profit":"20.00","method":"Не выбран","payment_id":"1618399991","description":"Покупка доступа на 2 дня","date":"2023-03-13 19:40:46","pay_date":"2023-03-13 19:40:46","transaction_status":"0","custom_fields":"null","webhook_status":"0","webhook_amount":"0"}}';
    $data = json_decode($response, true);
    $transaction_status = $data["1"]["transaction_status"];

    Затем вы можете использовать переменную $transaction_status в своих условиях if / else:

    if ($transaction_status == 0) {
      echo 'Статус транзакции = 0';
      exit(0);
    } else {
      echo 'Статус транзакции не равен 0';
    }

    Надеюсь, это поможет!
    Ответ написан
    5 комментариев
  • Как начинать массив с 1, а не с 0 в php?

    ValeriuCutebov
    @ValeriuCutebov
    В PHP массивы всегда начинаются с нуля, но вы можете создать массив, который начинается с 1, путем использования функции array_combine(), которая создает новый массив, используя один массив в качестве ключей, а другой - в качестве значений.

    В вашем случае, вы можете создать массив со значениями ключей, начиная с 1, используя цикл foreach для перебора пользователей и добавления их в новый массив с помощью функции array_combine(). Затем вы можете использовать новый массив вместо исходного для поиска пользователей и определения их индексов.

    protected function getServiceAccountId()
    {
      $serviceAccounts = $this->finder('XF:User')
        ->where('is_service_account', true)
        ->order('user_id')
        ->fetch()->toArray();
    
      $keyValues = range(1, count($serviceAccounts));
      $keyedAccounts = array_combine($keyValues, $serviceAccounts);
    
      foreach ($keyedAccounts as $key => $serviceAccount)
      {
        if ($serviceAccount->user_id == $this->user_id)
        {
          return $key;
        }
      }
    
      return $keyedAccounts;
    }

    В этом примере мы используем функцию range() для создания массива с числами от 1 до количества пользователей в $serviceAccounts. Затем мы используем array_combine(), чтобы создать новый массив $keyedAccounts, используя этот массив чисел в качестве ключей и $serviceAccounts в качестве значений.

    Далее мы используем новый массив $keyedAccounts вместо $serviceAccounts в цикле foreach для поиска пользователей и определения их индексов.

    Надеюсь, это поможет вам решить вашу проблему!
    Ответ написан
    Комментировать
  • Почему не возвращаются данные валидации inertia js + vue?

    ValeriuCutebov
    @ValeriuCutebov
    Если я правильно понял, что ошибка валидации возвращается при отлове реквеста, то проблема, вероятно, связана с тем, что вы не передаете ошибки обратно в представление после валидации.

    Чтобы исправить эту проблему, вам нужно передать ошибки обратно в представление, чтобы они могли быть отображены. В вашем коде я вижу, что у вас есть props errors в компоненте, который вы можете использовать для передачи ошибок из контроллера в представление.

    Попробуйте изменить функцию store в контроллере следующим образом, чтобы передать ошибки в представление:
    public function store(Request $request) {
        $valid = $request->validate(
            [
                'nickname'      => ['required','max:64','string'],
                'real_name'     => ['required','max:64','string'],
                'about'         => ['required','max:512','string'],
                'type'          => ['required','integer','max:4'],
                'forum_link'    => ['required','url'],
                'vkontakte'     => ['required','url'],
                'leaderships'   => ['required','string','max:512']
            ],
            [
                'nickname.required'     => 'Поле никнейм должно быть заполнено',
                'nickname.max'          => 'Максимум 64 символа',
                'nickname.string'       => 'Никнейм должен быть строкой',
                'real_name.required'    => 'Поле имя должно быть заполнено',
                'real_name.max'         => 'Максимум 64 символа',
                'real_name.string'      => 'Поле должно быть строкой',
                'about.required'        => 'Поле должно быть заполнено',
                'about.max'             => 'Максимум 512 символов',
                'about.string'          => 'Поле должно быть строкой',
                'type.required'         => 'Не выбран тип выдвижения',
                'vkontakte.required'    => 'Не указан вконтакте',
                'vkontakte.url'         => 'Вконтакте должен быть ссылкой',
                'leaderships.required'  => 'Лидерства должны быть заполнены',
                'leaderships.string'    => 'Error',
                'leaderships.max'       => 'Максимум 512 символов'
            ]
        );
    
        Conversation::query()->create([
            'user_id'       => Auth::id(),
            'nickname'      => $valid['nickname'],
            'about'         => $valid['about'],
            'real_name'     => $valid['real_name'],
            'leaderships'   => $valid['leaderships'],
            'who_close'     => null,
            'type'          => $valid['type'],
            'vkontakte'     => $valid['vkontakte'],
            'forum_link'    => $valid['forum_link']
        ]);
    
        return back()->withErrors($valid);
    }

    Для того чтобы получить ошибки в вашем компоненте, вы можете воспользоваться props, которые были переданы в компонент.

    В вашем коде вы передаете errors в качестве props в компонент. Чтобы отображать ошибки валидации, вам нужно проверить, есть ли ошибки в объекте errors, который передается в props.

    Также, во втором коде, в представлении нужно обращаться к ошибкам валидации через метод errors вместо props.errors, поэтому код должен выглядеть так:

    <template>
        <title>Добавить кандидата</title>
        <Navbar />
        <MDBRow center style="margin-bottom: 3%; margin-top: 3%;">
            <MDBCol md="6">
                <div class="card">
                    <div class="card-body">
                        <form @submit.prevent="submit">
                            <div v-if="errors.has('nickname')">{{ errors.first('nickname') }}</div>
                            <MDBInput type="text" label="Игровой ник" id="nickname" v-model="form.nickname" wrapperClass="mb-4" />
                            <div v-if="errors.has('real_name')">{{ errors.first('real_name') }}</div>
                            <MDBInput type="text" label="Реальное имя" id="real_name" v-model="form.real_name" wrapperClass="mb-4" />
                            <div v-if="errors.has('about')">{{ errors.first('about') }}</div>
                            <MDBInput type="text" label="О кандидате" id="about" v-model="form.about" wrapperClass="mb-3" />
                            <div v-if="errors.has('type')">{{ errors.first('type') }}</div>
                            <MDBRow class="mb-1">
                                <MDBCol class="d-flex justify-content-center">
                                    <MDBBtnGroup>
                                        <MDBRadio :btnCheck="true" :wrap="false" labelClass="btn btn-secondary" label="Администратор" name="options" value="1" v-model="form.type" />
                                        <MDBRadio :btnCheck="true" :wrap="false" labelClass="btn btn-secondary" label="Помощник" name="options" value="2" v-model="form.type" />
                                    </MDBBtnGroup>
                                </MDBCol>
                                <MDBCol class="d-flex justify-content-center">
                                    <MDBBtn type="submit" style="max-width: 80%;" color="primary" block> Начать выдвижение кандидата </MDBBtn>
                                </MDBCol>
                            </MDBRow>
                        </form>
                    </div>
                </div>
            </MDBCol>
        </MDBRow>
    </template>

    Обратите внимание на использование has и first методов вместо nickname и real_name, которые передаются в качестве ключей в массиве ошибок валидации.

    Надеюсь, это поможет вам решить проблему с отображением ошибок валидации в вашем приложении.
    Ответ написан
  • [CS CART] Как импортировать изображения по url?

    ValeriuCutebov
    @ValeriuCutebov
    Для импорта изображений по URL в CS-Cart можно использовать следующий алгоритм:

    1. Получите список товаров из базы данных с помощью функции fn_get_products.

    2. Проходите по списку товаров и получите URL-адрес изображения для каждого товара из вашего источника.

    3. Используйте функцию fn_update_product_image, чтобы добавить изображение для каждого товара. Функция принимает ID товара и URL-адрес изображения в качестве параметров.


    Пример PHP кода для добавления изображений по URL:
    $product_list = fn_get_products(array('product_id', 'product_code')); // Получить список товаров из базы данных
    foreach ($product_list as $product) {
        $image_url = 'http://example.com/image.jpg'; // URL-адрес изображения для товара
        $image_data = @file_get_contents($image_url); // Получить данные изображения по URL
        if ($image_data !== false) {
            $image_extension = pathinfo($image_url, PATHINFO_EXTENSION); // Получить расширение файла изображения
            $image_filename = $product['product_code'] . '.' . $image_extension; // Сформировать имя файла изображения
            $image_path = fn_update_product_image($product['product_id'], $image_filename, $image_data); // Добавить изображение и получить путь к файлу
            fn_update_product_image_pairs($product['product_id'], array($image_filename => array('main_pair' => true))); // Сделать изображение основным для товара
        }
    }

    Обратите внимание, что в примере используется функция file_get_contents для получения данных изображения по URL. Если вы используете HTTPS-соединение, то может потребоваться настройка SSL-сертификата на вашем сервере.

    Также функция fn_update_product_image_pairs используется для связывания изображения с товаром. В примере используется параметр 'main_pair' для установки основного изображения для товара, но вы можете использовать и другие параметры для связывания изображений с товаром.
    Ответ написан
    Комментировать
  • Копирование одного диска на несколько, как ускорить?

    ValeriuCutebov
    @ValeriuCutebov
    Если вы хотите скопировать один диск на несколько дисков, то вместо команды dd можно использовать cat. Например, чтобы скопировать содержимое /dev/sda на /dev/sdb, /dev/sdc и /dev/sdd, вы можете использовать следующую команду:
    cat /dev/sda | tee /dev/sdb /dev/sdc /dev/sdd > /dev/null

    Эта команда использует tee для записи содержимого /dev/sda на все три диска одновременно. Затем tee перенаправляет оригинальный вывод cat на /dev/null, чтобы избежать дополнительной записи.
    Ответ написан
    Комментировать
  • Как правильно подключать библиотеку на go?

    ValeriuCutebov
    @ValeriuCutebov
    В данном случае, вам нужно явно указать путь к библиотеке в файле go.mod и добавить суффикс ".git", чтобы он соответствовал пути, который требует go get.

    Вы можете сделать это, выполнив следующие шаги:

    Откройте файл go.mod в своем проекте и найдите строку с именем библиотеки.
    Измените ее, чтобы добавить суффикс ".git" к пути: bitbucket.test.lab/scm/~test/test_repo.git.
    Сохраните изменения в файле go.mod.

    Теперь вы можете запустить команду go get, и она должна успешно выполниться. Не забудьте также установить переменную окружения GOPRIVATE со значением bitbucket.test.lab/*, чтобы указать Go, что этот репозиторий должен быть считан из приватного репозитория.
    Ответ написан
    Комментировать
  • Почему сервер падает через AJAX запросы?

    ValeriuCutebov
    @ValeriuCutebov
    Скорее всего, причина падения сервера связана с тем, что каждый AJAX запрос создает новое соединение с базой данных, и эти соединения не закрываются после обработки запроса. Когда количество открытых соединений достигает определенного предела, сервер может перегрузиться и перестать отвечать на запросы.

    Для решения этой проблемы необходимо закрывать соединения с базой данных после обработки каждого запроса. Для этого можно использовать функцию mysqli_close() после выполнения запроса:

    $sql = "SELECT * FROM articles DESC LIMIT ".$startFrom.", 4";
    $res = mysqli_query($conn, $sql);
    $articles = array();
    while ($row = mysqli_fetch_assoc($res)){
    $articles[] = $row;
    }
    mysqli_close($conn);
    echo json_encode($articles);

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