R2m0x94 (Vasily)

R2m0x94 (Vasily)

Был в сети 01 декабря 2025, 19:28
Заказы принимаю
Николай Савин
Николай Савин
Василий, что-то ты мудришь сильно. Давай по порядку.
Для начала все это не движ от Symfony DB и Controllers. В MiniShop3 обычный классический PHP подход. Почитай про PSR-4, крайне рекомендую.

Во-вторых, про метод addPackage в MODX3 забудь. Это делается один раз автоматически при загрузке MODX. Далее MiniShop3, MODX, PHP уже знают про все классы, которые есть в каталоге /core/components/minishop3/src/

Если ты создаешь любой кастомный класс, например
/core/components/minishop3/src/Controllers/Cart/CartCustom.php
ты обязан использовать namespace. В твоем случае это будет
namespace MiniShop3\Controllers\Cart;
И полное имя подключаемого класса будет
MiniShop3\Controllers\Cart\CartCustom
Именно такое имя тебе нужно указывать в системных настройках или подключаемых сервисах.

Вот примерная заготовка для создания класса. расширяющего стандартную корзину

<?php

namespace MiniShop3\Controllers\Cart;  //  Обрати внимание это путь к каталогу Controllers\Cart\

use MiniShop3\Controllers\Cart\Cart;  //  Это мы подключили стандартный класс корзины, который будем переопределять

class CustomCart extents Cart
{
    //  Вот и все.  Класс подключен и расширен. Никаких addPackage
}

Ну и в системных настойках нужно указать имя расширенного класса (путь не нужен, он по namespace уже известен).

Я сделаю инструмент для подключения классов, без прописывания системных настроек
Будет отдельная инструкция.

Честно говоря, не до конца понимаю зачем ты в принципе лезешь в дебри, для тебя не понятные. Это разработка для программистов. Анонса всеобщего использования минишопа еще не было. Часть архитектуры еще не готова, то что готово, до конца не оттестировано. Если прям так тянет пощупать компонент — изучай то, что готово и анонсировано.
R2m0x94 (Vasily)
R2m0x94 (Vasily)
Добрый день, а где можно познакомится с методами записи и получения объектов к доступу таблиц?
Опробовав логически перебрать все варианты получилось соединиться с _msie_presets_fields
// Получение
$item = $modx->getObject('MsiePresetsFields', array('id' => 1));
// Запись
...
$item = $modx->newObject('MsiePresetsFields');
$item->fromArray($msie_2);
$item->save();
R2m0x94 (Vasily)
R2m0x94 (Vasily)
Пока нет, но будут новости — сообщу! Спасибо за рабочий пример)
{'!mFilter2' | snippet  : [
    'leftJoin' => '{
        "cfFieldPrices" : {
            "class" : "cfField",
            "alias" : "cfFieldPrices",
            "on" : "cfFieldPrices.city_id = ' ~ $_modx->getPlaceholder('current_city.id') ~ ' AND cfFieldPrices.placeholder = CONCAT(\'[pre]\', msProduct.id, \'_price[/pre]\')"
        }
    }',
    'select' => '{ "msProduct" : "*", "cfFieldPrices" : "cfFieldPrices.value AS cfprice" }'
]}
cronAbs
cronAbs
А вот этот код, передаёт нормально через конфиг:
<?php
class msCartCustomHandler extends msCartHandler {
    /**
    * msCartCustomHandler constructor.
    *
    * @param miniShop2 $ms2
    * @param array $config
    */
    public function __construct(miniShop2 $ms2, array $config = array())
    {
        $this->ms2 = $ms2;
        $this->modx = $ms2->modx;

        $cityFields = $this->modx->getService('cityfields','cityFields', $this->modx->getOption('cityfields.core_path', null, $this->modx->getOption('core_path').'components/cityfields/').'model/cityfields/');
        if ($cityFields instanceof cityFields) {
            if (!empty($cityFields->currentCityId)) {
                $currentCityId = $cityFields->currentCityId;
            }
            
        }
        $this->config = array_merge(array(
            'currentCityId' => $currentCityId,
            'cart' => & $_SESSION['minishop2']['cart'],
            'max_count' => $this->modx->getOption('ms2_cart_max_count', null, 1000, true),
            'allow_deleted' => false,
            'allow_unpublished' => false,
        ), $config);

        $this->cart = &$this->config['cart'];
        $this->modx->lexicon->load('minishop2:cart');

        if (empty($this->cart) || !is_array($this->cart)) {
            $this->cart = array();
        }
    }
    
   /**
     * @param array $data
     *
     * @return array
     */
    public function status($data = array())
    {
        $status = [
            'total_count' => 0,
            'total_cost' => 0,
            'total_weight' => 0,
            'total_discount' => 0,
            'total_positions' => count($this->cart),
        ];
        foreach ($this->cart as $item) {
            if (empty($item['ctx']) || $item['ctx'] == $this->ctx) {
                $status['total_count'] += $item['count'];
                $status['total_cost'] += $item['price'] * $item['count'];
                $status['total_weight'] += $item['weight'] * $item['count'];
                $status['total_discount'] += $item['discount_price'] * $item['count'];
            }
        }

        $status = array_merge($data, $status);

        $response = $this->ms2->invokeEvent('msOnGetStatusCart', [
            'status' => $status,
            'cart' => $this,
        ]);
        if ($response['success']) {
            $status = $response['data']['status'];
        }
        $this->modx->log(1, print_r($this->config['currentCityId'], 1));

        return $status;
    }
}
?>
R2m0x94 (Vasily)
R2m0x94 (Vasily)
На всякий случай если не заработает, то
// удаляем плагин
if ($miniShop2 = $modx->getService('miniShop2')) {
    $miniShop2->removePlugin('cart');
}
// добавляем вновь
$plugin = '{core_path}components/minishop2/plugins/cart/availability/index.php';
if ($miniShop2 = $modx->getService('miniShop2')) {
    $miniShop2->addPlugin('availability', $plugin);
}
// результат в ms2_plugins: {"availability":"{core_path}components\/minishop2\/plugins\/cart\/availability\/index.php"}

/* Вложенность иерархии в дереве и подключение, тоже имеют значение:
plugins
|_cart
|_|_availability
|_|_|_index.php
|_|_|_msproductdata.map.inc.php
*/
Евгений Лазарев
Евгений Лазарев
Уважаемые разработчики, хотел бы попросить. Можно ли в следующем релизе изменить формат телефона в msorderhandler.class.php? Каждый раз приходится строчку менять на
substr(preg_replace('/[^-+()0-9]/iu', '', $value), 0, 16);
Нужен многим формат +7(999)999-99-99, то есть и "+" нужен и скобки, а в общей сумме получается 16 символов. Буду очень признателен.
Александр Туниеков
Александр Туниеков
А вообще можно примерно так сделать простой редактор поля price
в чанке вывода результатов mfilter2 для поля price пишем:
<input type="number" class="autosave" data-product_id="[[+id]]" value="[[+price]]"/>
На страницу или в отдельный файл пишем скрипт
<script>
$(function() {
    $(document).on('change','.autosave',function(){
        $.post( "/assets/components/autosave/action.php", 
        { product_id: $(this).data('product_id'), value: $(this).val() })
          .done(function( data ) {
            alert( "Data Loaded: " + data );
          });
    });
});
</script>
Создаем файл /assets/components/autosave/action.php
<?php
define('MODX_API_MODE', true);
require_once dirname(dirname(dirname(dirname(__FILE__)))) . '/index.php';

$modx->getService('error', 'error.modError');
$modx->setLogLevel(modX::LOG_LEVEL_ERROR);
$modx->setLogTarget('FILE');

if (!$modx->user->hasSessionContext('mgr')){
    echo 'Access denied';
    exit;
}

if((int)$_POST['product_id'] > 0){
    if($product = $modx->getObject('msProduct',(int)$_POST['product_id']){
        $product->set('price', $_POST['price']);
        if($product->save()) echo 'success';
    }
}
Batys
Batys
Спасибо за наводку, разобрался и сделал так:
Сниппет addcart:
<?php
$miniShop2 = $modx->getService('minishop2');
$miniShop2->initialize($ctx, array('json_response' => $isAjax));
$article = $modx->getObject('msProductData', ['article' => $article]);
$miniShop2->cart->add($article->id, $count, $options);
Пример вызова:
[[!AjaxForm?
&snippet=`addcart`
&form=`tpl.AF.addcard`
&article=`11981000`
&count=`2`
]]
R2m0x94 (Vasily)
R2m0x94 (Vasily)
Впервые столкнулся с куки. Ранее не пробовал даже вникнуть в них. (
Первое, что пришло в голову после того, как хром с версией PHP 7.3 включил атрибут в куки `SameSite=None` and `Secure` or `SameSite=Lax`, так это добавить в $head элемент разметки
<meta http-equiv="set-cookie" content="name=yandex_login;lang=ru;expires=[[!+nowdate:default=`now`:strtotime:mpy=`1.002`:date=`%a, %e %b %Y %T`]] GMT;domain=.yandex.ru;path=/;SameSite=None;Secure" />
Но консоль не убрала предупреждений, а наоборот сообщила об ошибке.
Blocked setting the `name=yandex_login;lang=ru;expires= GMT;domain=.yandex.ru;path=/;SameSite=None;Secure` cookie from a `<meta>` tag.
Читал про это
тут и тут, но решение получить куки сниппетом или исходя из этого решенияпроблему решить не удалось. Знаю только, что некоторые из них есть в Инструментах разработчика «Applications > Cookies (Storage)

Возможно, кто-то уже сталкивался с кукисами. Подскажите, как сделать сниппет [[!getCookie]] и [[!setCookie]]. И как пользоваться ими, для того чтобы предупреждения в консоле пропали о межсайтовых ресурсах <url>?

UPD: Чтобы не плодить кучу топиков ещё ссылка MODX session и cookie — помогите разобраться (https://modx.pro/help/8159)
Петропавловский Артем
Петропавловский Артем