Николай Савин

Николай Савин

С нами с 01 января 1970; Место в рейтинге пользователей: #2
4 часа назад
0
MODX, как и любой основанный на PHP фреймворк пишет 500 ошибки в error_log. Никаких специальных настроек в нем нет. Все зависит от настроек хостинга\сервера. Бывает что запись ошибок просто отключена, бывает что путь к журналу ошибок нестандартный. Короче вряд ли вопрос именно в MODX.
Вчера в 20:05
+1
Набросал вариант реализации плагина, чтобы можно было его вызвать дважды, передать изменения из первого во второй и применить оба изменения. При использовании $modx->eventData все работает.
<?php
  /**
   * Плагин: msDiscount10_v2
   * События: msOnGetCart
   *
   * Используем $modx->eventData для передачи между плагинами
   */

  switch ($modx->event->name) {
      case 'msOnGetCart':
          // Читаем данные: из $modx->eventData (если предыдущий плагин записал)
          // или из $scriptProperties (оригинальные)
          if (isset($modx->eventData['msOnGetCart']['data'])) {
              $data = $modx->eventData['msOnGetCart']['data'];
          } else {
              $data = $scriptProperties['data'];
          }

          if (!is_array($data) || empty($data)) {
              break;
          }

          // Применяем скидку 10%
          foreach ($data as $key => $item) {
              $data[$key]['price'] = $item['price'] * 0.9;
              $data[$key]['cost'] = $data[$key]['price'] * $item['count'];
          }

          // Сохраняем для следующих плагинов
          $modx->eventData['msOnGetCart']['data'] = $data;

          // И для контроллера MS3
          $modx->event->returnedValues['data'] = $data;
          break;
  }
Справедливости ради, в некоторых местах $modx->eventData игнорируется. Это исправлю к следующему релизу
Вчера в 19:20
0
{$_modx->runSnippet("!msCart", [])}
В корзине теперь есть обязательный параметр selector, где мы прописываем обычный JS селектор. Корзин может быть много. JS должен понимать куда монтировать обновленные данные.

Как это работает:
  1. При вызове msCart сниппет регистрирует себя с уникальным токеном
  2. После добавления товара сервер возвращает отрендеренный HTML с этим токеном
  3. JavaScript (CartUI.js:316-318) ищет selector чтобы знать куда вставить HTML
  4. Если selector не указан — обновление пропускается
Решение:

Оберните корзину в контейнер с id и укажите параметр selector:

<div id="header-cart">
      {$_modx->runSnippet('!msCart', [
          'selector' => '#header-cart',
          'tpl' => 'tpl.msMiniCart'
      ])}
  </div>
Или короче через Fenom:

<div id="header-cart">
      {'!msCart' | snippet : ['selector' => '#header-cart', 'tpl' => 'tpl.msMiniCart']}
  </div>
Важно:
  • selector — CSS-селектор контейнера куда будет монтироваться обновлённый HTML
  • Контейнер должен оборачивать вызов сниппета (HTML заменяется внутри него)
  • Для мини-корзины в шапке лучше использовать чанк tpl.msMiniCart
Вчера в 19:03
0
Deprecated: Optional parameter $options declared before required parameter $info is implicitly treated as a required parameter in ....../core/components/minishop3/src/Model/msProductFile.php on line 201
Это известная проблема совместимости с PHP 8.0+. В файле msProductFile.php на строке 201 необязательный параметр объявлен перед обязательным, что устарело в PHP 8.

Временное решение:

Откройте файл core/components/minishop3/src/Model/msProductFile.php и измените строку 201:

// Было:
  public function makeThumbnail($options = [], array $info)

  // Стало:
  public function makeThumbnail(array $options, array $info)
Это временный фикс. Исправление будет включено в следующее обновление MiniShop3.
Вчера в 14:58
0
Для добавления полей во все основные модели заложена специальная утилита (msCustomer там сейчас нет, добавлю). Добавляешь поля через этот визуальный конструктор. Далее работаешь с ними как с родными. Просто выводишь и сохраняешь.
Вчера в 14:56
0
1) Так я вроде в каждом анонсе пишу, что делаю конфигурируемые страницы. У нас уже есть возможность не городить плагины, а добавлять поля в модели централизовано из одного места. Также и во всех основных страницах админки стараюсь сделать возможность добавлять поля в нужном месте страницы. Это тоже централизовано из одной утилиты.

Итого у нас есть две утилиты
1. Добавление полей в базу данных и в карту модели.
2. Добавление полей на страницу админки.

Есть еще третья утилиты — вывод колонок в таблицах-гридах.

2) Нет с плагинами ничего не делал. Проблему я понял. Подумаю что можно сделать
25 декабря 2025, 13:57
0
Ну тогда уж и плюсик ставь к посту.
24 декабря 2025, 21:22
0
В системную настройку mail_smtp_pass (SMTP пароль) вписываете пароль приложения, вместо пароля от почты и все. Никакой магии нет.
24 декабря 2025, 20:42
0
Задача закрыть все потребности никогда не стояла. Я скорее облагородил то, что уже было.
Нужно же и платным компонентам дорогу для развития оставлять.
24 декабря 2025, 20:41
0
  1. Неправильные права на директорию core/packages/
  2. Файл zip загружен с неправильным владельцем
24 декабря 2025, 19:37
+1
@Prihod специально для тебя выпустил релиз пораньше, чтобы ты смог скачать свежий транспортник
24 декабря 2025, 00:23
0
Нет, лайки всегда были привязаны ко времени публикации, чтобы лайками старых постов рейтинг не накручивали.
23 декабря 2025, 19:58
0
Спасибо проверю. Подскажи как устанавливал? Скачал готовый транспортник из релизов или из git исходников собрал?
15 декабря 2025, 19:40
0
Привет Григорий.

Осадочек обоснованный — решение рабочее, но есть несколько моментов, которые стоит обдумать:

Что смущает в текущем фиксе

1. Изменение логики метода.
Оригинальный код при отсутствии сессии возвращал []. Теперь он создаёт сессию. Это может сломать логику в других местах SendIt, которые рассчитывают на пустой ответ как сигнал «сессии нет, нужно что-то сделать».

2. setcookie() без проверки заголовков
Если заголовки уже отправлены — будет ещё один warning.

Минимальный и безопасный фикс
Если цель — просто убрать warning без изменения логики:
$sessionId = $sessionId ?: ($_COOKIE['siSession'] ?? null);

if (!$sessionId || !$session = $modx->getObject('siSession', ['session_id' => $sessionId, 'class_name' => $className])) {
    return [];
}
Это сохраняет оригинальное поведение: нет куки → нет сессии → пустой массив. Создание сессии должно происходить там, где это предусмотрено архитектурой компонента.

Что бы я сделал

Посмотрел бы, где в SendIt сессия создаётся штатно. Скорее всего есть отдельный метод типа createSession() или это происходит при первой отправке формы. Вот там и должна быть логика создания + установки куки.

Твой фикс работает, но ты фактически добавил fallback-создание сессии в метод, который был рассчитан только на чтение. Если форма авторизации/регистрации работает корректно — можно оставить, но я бы откатился к минимальному варианту и понаблюдал.
08 декабря 2025, 10:53
0
По правильному нужно адаптировать проект под PHP8.1 — хуже от этого точно не станет, зато у вас появится возможность использовать более современные компоненты.
Из минусов — можно потерять возможность обновлять некоторые старые компоненты (правда они особо и не обновляются)
Ну и затратно может быть.
30 ноября 2025, 19:10
+2
У msCustomer есть поле user_id, которое связывает покупателя с modUser:

// В модели msCustomer
  'aggregates' => [
      'User' => [
          'class' => 'MODX\\Revolution\\modUser',
          'local' => 'user_id',
          'foreign' => 'id',
          'cardinality' => 'one',
      ],
  ],
Режимы работы

1. Автономный режим (по умолчанию)
  • msCustomer работает независимо от modUser
  • Покупатели авторизуются через свой email/пароль
  • Подходит для магазинов без дополнительного функционала

2. Синхронизация с modUser
  • Включается настройкой ms3_customer_sync_enabled
  • При создании/обновлении modUser автоматически создаётся/обновляется msCustomer
  • Синхронизируются: email, fullname → first_name, phone, активность
  • При удалении modUser — покупатель НЕ удаляется (сохраняется история заказов), только отвязывается (user_id = 0)

3. Создание modUser при заказе
  • Настройка ms3_order_register_user_on_submit
  • При оформлении заказа создаётся системный пользователь
  • Ему можно назначить права и группу пользователей
30 ноября 2025, 14:25
+2
Для желающих протестировать — создал релиз в GitHub. Там можно скачать готовый транспортный пакет.