Всего 125 447 комментариев

Артур Шевченко
5 часов назад
0
Вариант 1
Переопределить метод msOrderHandler::submit() таким образом, чтобы там перед установлением статуса «Новый» проверялся способ оплаты и, если оплата при получении, статус устанавливать методом minishop2::changeOrderStatus(), иначе через modResource::save().

Вариант 2.
Ввести для оплаты при получении отдельный статус. Написать плагин на событие msOnChangeOrderStatus, в котором проверять способ оплаты и, если это оплата при получении, вызывать метод minishop2::changeOrderStatus() и устанавливать созданный для этого способа оплаты статус. При этом отправку писем для статуса «Новый» отключить в настройках минишопа.

Вариант 3.
Отключить стандартную отправку писем. Написать свой класс отправки писем и вызывать его в плагине на событие msOnChangeOrderStatus. Вот пример реализации такого класса
<?php

namespace CustomServices\Manage;

use CustomServices\Helpers\Mailer;

class MailingOrder extends Base
{
    private Mailer $mailer;

    private array $mailingStatuses = [
        2 => [
            'user' => [
                'subject' => 'ms2_email_subject_paid_user',
                'chunk' => 'msEmailPaid.user'
            ],
            'manager' => [],
        ],
        3 => [
            'user' => [
                'subject' => 'ms2_email_subject_sent_user',
                'chunk' => 'msEmail.sent.user'
            ],
            'manager' => [],
        ],
        108 => [
            'user' => [
                'subject' => 'ms2_email_subject_sent_user',
                'chunk' => 'msEmail.sent.user'
            ],
            'manager' => [],
        ],
        117 => [
            'user' => [
                'subject' => 'ms2_email_subject_paid_user',
                'chunk' => 'msEmailPaid.user'
            ],
            'manager' => [],
        ],
        103 => [
            'user' => [
                'subject' => 'ms2_email_subject_paid_user',
                'chunk' => 'msEmailPaid.user'
            ],
            'manager' => [],
        ],
    ];

    private array $statusData;

    public function __construct(\modX $modx, ?array $properties = [])
    {
        parent::__construct($modx, $properties);
        if ($properties['order'] && $properties['order']->get('context') !== $this->modx->context->get('key')) {
            $this->modx->switchContext($properties['order']->get('context'));
            $this->cultureKey = $this->modx->getOption('cultureKey', '', 'en');
        }
        $this->mailer = new Mailer($this->modx);
        $this->statusData = [];
    }

    public function send(): bool
    {
        $statusId = $this->properties['statusId'];
        if (!isset($this->mailingStatuses[$statusId])) {
            return false;
        }
        $this->statusData = $this->mailingStatuses[$statusId];

        if (!$this->properties['order']) {
            $this->logging->write([
                'msg' => "Mail not sent. Order not defined",
            ]);
            return false;
        }

        $pls = $this->getEmailPls();
        if (!empty($this->statusData['manager']) && $mgrMailerProps = $this->getMailerProperties($pls, 'manager')) {
            if(!$this->mailer->send($mgrMailerProps)){
                $this->logging->write([
                    'msg' => "Order {$pls['num']} was not sent to manager email",
                    'data'=> [
                        'mailerProps' => $mgrMailerProps
                    ]
                ]);
            }
        }

        if (!empty($this->statusData['user']) && $usrMailerProps = $this->getMailerProperties($pls)) {
            if(!$this->mailer->send($usrMailerProps)){
                $this->logging->write([
                    'msg' => "Order {$pls['num']} was not sent to customer email",
                    'data'=> [
                        'mailerProps' => $usrMailerProps
                    ]
                ]);
            }
        }
        return true;
    }

    public function getEmailPls(): array
    {
        $pls = $this->properties['order']->toArray();
        $pls['cost'] = $this->miniShop2->formatPrice($pls['cost']);
        $pls['cart_cost'] = $this->miniShop2->formatPrice($pls['cart_cost']);
        $pls['delivery_cost'] = $this->miniShop2->formatPrice($pls['delivery_cost']);
        $pls['weight'] = $this->miniShop2->formatWeight($pls['weight']);
        $pls['payment_link'] = $this->properties['paymentLink'] ?: '';
        return $pls;
    }

    public function getMailerProperties(array $pls, $type = 'user'): array
    {
        $mailerProperties = [];
        $mailerProperties['subject'] = $this->modx->lexicon($this->statusData[$type]['subject'], $pls, $this->cultureKey);
        if($mailerProperties['subject'] === $this->statusData[$type]['subject']){
            $mailerProperties['subject'] = $this->modx->lexicon($this->statusData[$type]['subject'], $pls, 'en');
        }
        $mailerProperties['body'] = $this->parser->runSnippet('msGetOrder', array_merge($pls, ['tpl' => $this->statusData[$type]['chunk']]));
        if ($this->properties['invoicePath'] && $type === 'user') {
            $mailerProperties['attachment'] = $this->properties['invoicePath'];
        }

        if (!$mailerProperties['to'] = $type === 'user' ? $this->getUserEmails($pls['user_id']) : $this->getManagerEmails()) {
            return [];
        }

        return $mailerProperties;
    }

    public function getUserEmails(int $userId): array
    {
        if (!$profile = $this->modx->getObject('modUserProfile', ['internalKey' => $userId])) {
            return [];
        }
        $email = $profile->get('email');
        if (!$email) {
            if (!$user = $this->modx->getObject('modUser', $userId)) {
                return [];
            }
            if (!$email = $user->get('username')) {
                return [];
            }
        }
        return [$email];
    }

    public function getManagerEmails(): array
    {
        return array_map(
            'trim',
            explode(
                ',',
                $this->modx->getOption('ms2_email_manager', null, $this->modx->getOption('emailsender'))
            )
        );
    }
}
vectorserver
Вчера в 11:23
0
Вот давно для себя писал: modx.pro/solutions/18489
или через мускул (перед выполнением обязательно сделайте дамп) напрямую + потом кеш почистить
UPDATE modx_site_content t1
JOIN (
    SELECT 
        id,
        CONCAT(alias, '-', ROW_NUMBER() OVER (PARTITION BY uri ORDER BY id ASC)) AS new_alias
    FROM 
        modx_site_content 
    WHERE 
        uri IN (
            SELECT uri 
            FROM modx_site_content 
            GROUP BY uri 
            HAVING COUNT(*) > 1
        )
        AND deleted = 0
) t2 ON t1.id = t2.id
SET 
    t1.alias = t2.new_alias
WHERE 
    t2.new_alias != t1.alias;
vectorserver
Вчера в 11:10
0
Надо глянуть структуру XML что именно поменялось, если что пишите в ЛС могу посмотреть.
vectorserver
Вчера в 11:06
0
Используй phpThumbOn он как раз в префиксе указывает размер изображения.
Ссылка: modstore.pro/packages/photos-and-files/phpthumbon
Николай Савин
14 января 2026, 15:11
0
Да особо без разницы куда писать. Я отслеживаю все записи. Но в идеале создавать issue в репозитории github.com/modx-pro/MiniShop3/issues.
Evgeny Epifanov
14 января 2026, 14:47
0
Ну, тогда, пока не забыл...)
Импорт товаров.
  • Не работает dragndrop, через файловый менеджер все работает.
  • Не нашел соответствия полю class_key, а ведь категории товаров тоже хочется импортировать.
  • Полю parent соответствует «Категория». Долго не мог найти соответствие типа «Родитель». Просто ввело в заблуждение.
  • Не отображаются свои поля
  • Что делает соответствие «ms3_import_skip_column»? Первое в списке
  • Все соответствия прописаны на русском, опции (свойства товара) товара выводятся по ключу. Видимо из-за лексиконов. Конечно, это не критично.
  • После успешного импорта: Обработано: 0 Создано: 0 Обновлено: 0
Как же круто, что система подтягивает нужные наименование полей по заголовкам *.csv!
Извиняюсь, что пишу сюда. Николай, куда лучше писать про замеченные ошибки?
Николай Савин
14 января 2026, 13:36
+1
Тебе спасибо за обратную связь. 100 человек прошли бы мимо, а ты написал и протестировал.
Evgeny Epifanov
14 января 2026, 13:17
+1
Вроде все нормально.
Поля создаются.
Огромное спасибо за компонент и за оперативное решение вопросов!
Николай Савин
14 января 2026, 12:42
0
Внес исправления еще раз, хорошо с нуля все проверил. Обновил в modstore, можно попробовать переустановить
Evgeny Epifanov
14 января 2026, 11:40
0
На поддомен вынес.
Консоль запущена...
Пробуем установить пакет с подписью: minishop3-1.1.0-beta1
Пакет найден... сейчас идёт подготовка к его установке.
Загрузка рабочего пространства пакета...
Рабочее пространство загружено, сейчас устанавливаем пакет...
[MiniShop3] Starting database migrations...
PHP warning: Constant MODX_CORE_PATH already defined
PHP warning: Constant MODX_CONFIG_KEY already defined
[MiniShop3] Migration execution failed: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'grid_key' in 'INSERT INTO'
[MiniShop3] Migration error: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'grid_key' in 'INSERT INTO'
[MiniShop3] Stack trace: #0 /var/www/dev1/www/core/components/minishop3/vendor/robmorgan/phinx/src/Phinx/Db/Adapter/PdoAdapter.php(462): PDOStatement->execute() #1 /var/www/dev1/www/core/components/minishop3/vendor/robmorgan/phinx/src/Phinx/Db/Adapter/AdapterWrapper.php(186): Phinx\Db\Adapter\PdoAdapter->bulkinsert() #2 /var/www/dev1/www/core/components/minishop3/vendor/robmorgan/phinx/src/Phinx/Db/Adapter/TimedOutputAdapter.php(103): Phinx\Db\Adapter\AdapterWrapper->bulkinsert() #3 /var/www/dev1/www/core/components/minishop3/vendor/robmorgan/phinx/src/Phinx/Db/Adapter/AdapterWrapper.php(186): Phinx\Db\Adapter\TimedOutputAdapter->bulkinsert() #4 /var/www/dev1/www/core/components/minishop3/vendor/robmorgan/phinx/src/Phinx/Db/Adapter/TablePrefixAdapter.php(373): Phinx\Db\Adapter\AdapterWrapper->bulkinsert() #5 /var/www/dev1/www/core/components/minishop3/vendor/robmorgan/phinx/src/Phinx/Db/Table.php(662): Phinx\Db\Adapter\TablePrefixAdapter->bulkinsert() #6 /var/www/dev1/www/core/components/minishop3/vendor/robmorgan/phinx/src/Phinx/Db/Table.php(622): Phinx\Db\Table->saveData() #7 /var/www/dev1/www/core/components/minishop3/vendor/robmorgan/phinx/src/Phinx/Db/Table.php(694): Phinx\Db\Table->create() #8 /var/www/dev1/www/core/components/minishop3/migrations/20251127000002_seed_customers_grid_config.php(148): Phinx\Db\Table->save() #9 /var/www/dev1/www/core/components/minishop3/vendor/robmorgan/phinx/src/Phinx/Migration/Manager/Environment.php(112): SeedCustomersGridConfig->up() #10 /var/www/dev1/www/core/components/minishop3/vendor/robmorgan/phinx/src/Phinx/Migration/Manager.php(413): Phinx\Migration\Manager\Environment->executeMigration() #11 /var/www/dev1/www/core/components/minishop3/vendor/robmorgan/phinx/src/Phinx/Migration/Manager.php(384): Phinx\Migration\Manager->executeMigration() #12 /var/www/dev1/www/core/packages/minishop3-1.1.0-beta1/MODX/Revolution/modCategory/fb0516c1046b88fd6bb943da8b601bef.resolver_02_migrations.resolver(76): Phinx\Migration\Manager->migrate() #13 /var/www/dev1/www/core/vendor/xpdo/xpdo/src/xPDO/Transport/xPDOVehicle.php(216): include('...') #14 /var/www/dev1/www/core/vendor/xpdo/xpdo/src/xPDO/Transport/xPDOObjectVehicle.php(218): xPDO\Transport\xPDOVehicle->resolve() #15 /var/www/dev1/www/core/vendor/xpdo/xpdo/src/xPDO/Transport/xPDOObjectVehicle.php(77): xPDO\Transport\xPDOObjectVehicle->_installObject() #16 /var/www/dev1/www/core/vendor/xpdo/xpdo/src/xPDO/Transport/xPDOTransport.php(263): xPDO\Transport\xPDOObjectVehicle->install() #17 /var/www/dev1/www/core/src/Revolution/Transport/modTransportPackage.php(346): xPDO\Transport\xPDOTransport->install() #18 /var/www/dev1/www/core/src/Revolution/Processors/Workspace/Packages/Install.php(73): MODX\Revolution\Transport\modTransportPackage->install() #19 /var/www/dev1/www/core/src/Revolution/Processors/Processor.php(208): MODX\Revolution\Processors\Workspace\Packages\Install->process() #20 /var/www/dev1/www/core/src/Revolution/modX.php(1781): MODX\Revolution\Processors\Processor->run() #21 /var/www/dev1/www/core/src/Revolution/modConnectorResponse.php(151): MODX\Revolution\modX->runProcessor() #22 /var/www/dev1/www/core/src/Revolution/modConnectorRequest.php(89): MODX\Revolution\modConnectorResponse->outputContent() #23 /var/www/dev1/www/core/src/Revolution/modConnectorRequest.php(77): MODX\Revolution\modConnectorRequest->prepareResponse() #24 /var/www/dev1/www/connectors/index.php(79): MODX\Revolution\modConnectorRequest->handleRequest() #25 {main}
✅ [MiniShop3] Manager API custom routes file created at: core/config/ms3_routes_manager.custom.php
This file will NEVER be overwritten. Safe to customize!
[MiniShop3] Could not create Web API custom routes example (optional)
📁 [MiniShop3] System routes are in: core/components/minishop3/config/routes/
[MiniShop3] Scheduled first run for recurring task 'ms3_cleanup_drafts'
[MiniShop3] Scheduled first run for recurring task 'ms3_cleanup_tokens'
[MiniShop3] Scheduler tasks: 4 registered, 0 updated
[MiniShop3] Recurring tasks enabled: ms3_cleanup_drafts (daily), ms3_cleanup_tokens (weekly).
Успешно установлен пакет minishop3-1.1.0-beta1
Николай Савин
14 января 2026, 11:16
0
Внес правку и перевыпустил компонент без изменения версии. Попробуй удали пакет, если он установлен и скачай из modstore заново. Жду обратную связь.
Важно — убедись что все таблицы были удалены из базы данных (они при удалении компонента не удаляются) В том числе удали таблицу ms3_migrations
Николай Савин
14 января 2026, 10:31
0
Будет еще лучше. mFilter на подходе!
Evgeny Epifanov
14 января 2026, 10:27
0
Да, это все же критично. Миграции не работают. При создании своего дополнительного поля возникает ошибка.
Ошибка создания
Migration execution error: SQLSTATE[HY000]: General error: 1364 Field 'created_at' doesn't have a default value
Сергей
14 января 2026, 10:05
+1
Честно говоря, давно бы перешел на modx 3, но удерживало отсутствие важных компонентом. Спасибо за ваш труд! Поддержал покупкой компонента!
Александр
13 января 2026, 20:13
+3
MODX на данный момент, на мой взгляд, единственная адекватная система для построения любых сайтов.
Я пробовал Ларавель, пробовал Джанго, это фреймворки, не говоря про различные CMS. На модексе гораздо комфортнее, логичнее и проше.
Года с 2012 делаю исключительно на модекс, начинал с ЭВО.
Данная новость это настоящий прорыв, которого дооолго ждали и хотелось бы надеяться что модекс продолжит свое развитие.
Спасибо за труд.
Николай Савин
13 января 2026, 20:04
0
Довольно критично. Некоторые таблицы могли не создаться. Это мы поправим.
Уточни пожалуйста, какая версия СУБД используется?
Evgeny Epifanov
13 января 2026, 15:15
+1
На абсолютно чистой системе, при установке такие ошибки:
Консоль запущена...
Пробуем установить пакет с подписью: minishop3-1.1.0-beta1
Пакет найден... сейчас идёт подготовка к его установке.
Загрузка рабочего пространства пакета...
Рабочее пространство загружено, сейчас устанавливаем пакет...
[MiniShop3] Starting database migrations...
PHP warning: Constant MODX_CORE_PATH already defined
PHP warning: Constant MODX_CONFIG_KEY already defined
[MiniShop3] Migration execution failed: SQLSTATE[HY000]: General error: 1364 Field 'created_at' doesn't have a default value
[MiniShop3] Migration error: SQLSTATE[HY000]: General error: 1364 Field 'created_at' doesn't have a default value
[MiniShop3] Stack trace: #0 /var/www/modx3/www/core/components/minishop3/vendor/robmorgan/phinx/src/Phinx/Db/Adapter/PdoAdapter.php(462): PDOStatement->execute() #1 /var/www/modx3/www/core/components/minishop3/vendor/robmorgan/phinx/src/Phinx/Db/Adapter/AdapterWrapper.php(186): Phinx\Db\Adapter\PdoAdapter->bulkinsert() #2 /var/www/modx3/www/core/components/minishop3/vendor/robmorgan/phinx/src/Phinx/Db/Adapter/TimedOutputAdapter.php(103): Phinx\Db\Adapter\AdapterWrapper->bulkinsert() #3 /var/www/modx3/www/core/components/minishop3/vendor/robmorgan/phinx/src/Phinx/Db/Adapter/AdapterWrapper.php(186): Phinx\Db\Adapter\TimedOutputAdapter->bulkinsert() #4 /var/www/modx3/www/core/components/minishop3/vendor/robmorgan/phinx/src/Phinx/Db/Adapter/TablePrefixAdapter.php(373): Phinx\Db\Adapter\AdapterWrapper->bulkinsert() #5 /var/www/modx3/www/core/components/minishop3/vendor/robmorgan/phinx/src/Phinx/Db/Table.php(662): Phinx\Db\Adapter\TablePrefixAdapter->bulkinsert() #6 /var/www/modx3/www/core/components/minishop3/vendor/robmorgan/phinx/src/Phinx/Db/Table.php(634): Phinx\Db\Table->saveData() #7 /var/www/modx3/www/core/components/minishop3/vendor/robmorgan/phinx/src/Phinx/Db/Table.php(692): Phinx\Db\Table->update() #8 /var/www/modx3/www/core/components/minishop3/migrations/20251127000002_seed_customers_grid_config.php(141): Phinx\Db\Table->save() #9 /var/www/modx3/www/core/components/minishop3/vendor/robmorgan/phinx/src/Phinx/Migration/Manager/Environment.php(112): SeedCustomersGridConfig->up() #10 /var/www/modx3/www/core/components/minishop3/vendor/robmorgan/phinx/src/Phinx/Migration/Manager.php(413): Phinx\Migration\Manager\Environment->executeMigration() #11 /var/www/modx3/www/core/components/minishop3/vendor/robmorgan/phinx/src/Phinx/Migration/Manager.php(384): Phinx\Migration\Manager->executeMigration() #12 /var/www/modx3/www/core/packages/minishop3-1.1.0-beta1/MODX/Revolution/modCategory/f614c4b6a105e07a28f3505f9d13c876.resolver_02_migrations.resolver(76): Phinx\Migration\Manager->migrate() #13 /var/www/modx3/www/core/vendor/xpdo/xpdo/src/xPDO/Transport/xPDOVehicle.php(216): include('...') #14 /var/www/modx3/www/core/vendor/xpdo/xpdo/src/xPDO/Transport/xPDOObjectVehicle.php(218): xPDO\Transport\xPDOVehicle->resolve() #15 /var/www/modx3/www/core/vendor/xpdo/xpdo/src/xPDO/Transport/xPDOObjectVehicle.php(77): xPDO\Transport\xPDOObjectVehicle->_installObject() #16 /var/www/modx3/www/core/vendor/xpdo/xpdo/src/xPDO/Transport/xPDOTransport.php(263): xPDO\Transport\xPDOObjectVehicle->install() #17 /var/www/modx3/www/core/src/Revolution/Transport/modTransportPackage.php(346): xPDO\Transport\xPDOTransport->install() #18 /var/www/modx3/www/core/src/Revolution/Processors/Workspace/Packages/Install.php(73): MODX\Revolution\Transport\modTransportPackage->install() #19 /var/www/modx3/www/core/src/Revolution/Processors/Processor.php(208): MODX\Revolution\Processors\Workspace\Packages\Install->process() #20 /var/www/modx3/www/core/src/Revolution/modX.php(1781): MODX\Revolution\Processors\Processor->run() #21 /var/www/modx3/www/core/src/Revolution/modConnectorResponse.php(151): MODX\Revolution\modX->runProcessor() #22 /var/www/modx3/www/core/src/Revolution/modConnectorRequest.php(89): MODX\Revolution\modConnectorResponse->outputContent() #23 /var/www/modx3/www/core/src/Revolution/modConnectorRequest.php(77): MODX\Revolution\modConnectorRequest->prepareResponse() #24 /var/www/modx3/www/connectors/index.php(79): MODX\Revolution\modConnectorRequest->handleRequest() #25 {main}
✅ [MiniShop3] Manager API custom routes file created at: core/config/ms3_routes_manager.custom.php
This file will NEVER be overwritten. Safe to customize!
[MiniShop3] Could not create Web API custom routes example (optional)
📁 [MiniShop3] System routes are in: core/components/minishop3/config/routes/
[MiniShop3] Scheduled first run for recurring task 'ms3_cleanup_drafts'
[MiniShop3] Scheduled first run for recurring task 'ms3_cleanup_tokens'
[MiniShop3] Scheduler tasks: 4 registered, 0 updated
[MiniShop3] Recurring tasks enabled: ms3_cleanup_drafts (daily), ms3_cleanup_tokens (weekly).
Успешно установлен пакет minishop3-1.1.0-beta1
Насколько это критично?
Николай Савин
13 января 2026, 09:17
0
Фидбек куда тебе удобно. Я везде читаю.

ms3 просит установить VueTools даже после его установки
Ну чет пока у тебя одного только просит. Попробуй обновить страницу через CTRL + F5
Андрей
13 января 2026, 00:35
0
Круто! Ждем! Куда фидбекать по ошибкам? ms3 просит установить VueTools даже после его установки