Евгений Шеронов

Евгений Шеронов

С нами с 20 мая 2015; Место в рейтинге пользователей: #33
Евгений Шеронов
05 июля 2021, 15:51
+1
Решение хорошее.

Но раз это готовое бесплатное решение, то позволите мне немного рекламы?)

Для тех кто хочет визуально управлять элементами с описаниями полей, выгружать большие объемы точно валидного XML и не трогать код — то выгрузка под похожий формат Google Rss 2.0 (это Гугл покупки, и что-то для Фейсбука) есть в компоненте YandexMarket2 (пост о добавлении такого типа выгрузок писать не стал, инфа была только в changelog)
Евгений Шеронов
29 мая 2021, 11:38
0
Я сам с тобой делился настройкой CORS выше))
Там где ещё куки пишутся для авторизации.

И эта политика распространяется только на один контроллер компонента, а не на весь MODX, и только тогда, когда мне это нужно))

Я видимо слишком подробно и запутанно объясняю)
Евгений Шеронов
28 мая 2021, 23:13
+1
Не совсем так, у меня просто MODX стоит на сервере и все файлы синхронизируются туда.
По сути просто фронтенд приложение работает на localhost, а весь бэкенд на реальном домене.
Ещё через шторм часто пишу и проверяю SQL запросы подключаясь к БД через ssh туннель)

Да и не вставляю я руками скрипт) этот коннектор всегда такой в ветке dev. В ветке master всё чисто, на которую я и переключаюсь для вливания изменений и для сборки транспортного пакета (именно на ветке master я уже не могу из локального фронтенда подключиться к бэкенду на сервере из-за CORS).

Заготовки же MODX + Vue.js были в статьях на которые я ссылался в своей статье. Там даже установочный скрипт был, но я его не использовал.

Когда начну и допишу документацию по маркету — то попробую поделиться как раз своими конфигами или может целую заготовку сделаю modExtraVuetify. Но это не в ближайшие недели)
Евгений Шеронов
26 мая 2021, 15:26
0
Вы не понимаете, это другое)

По axios с одной стороны да, привычка.
Но с другой стороны это более лаконичный синтаксис по сравнению с нативным fetch.
В axios проще засеттить значения по умолчанию: в моём случае адрес коннектора и заголовки именно там, где эти значения получены. Чуть проще обрабатывать HTTP ошибки (хотя к MODX это плохо относится, другая парадигма ответов).

Axios я использую не потому что привык это делать в мире MODX и jQuery, а потому что увидел его уже в мире Vue.js и видел регулярно. Да и вообще он появился раньше, чем появился fetch)

Переходя на другую технологию может и было бы легче использовать старые добрые инструменты (тот же jQuery.ajax()), но потом приходит понимание, что не просто так же используются другие решения (иногда просто так :) )

В своё время jQuery был прекрасным инструментом, но сейчас это уже legacy — развитие браузеров и JavaScript оставило его не у дел. И теперь уже нет такой нужды использовать его. Конечно, полно сайтов ещё долго будут использовать jQuery, но чем дальше — тем болезненнее слезать.

И уж точно не нужно его приносить в другой мир, где есть инструменты, которые решают те же задачи, но по-своему (обычно лучше, быстрее, надёжнее и т.д.).

И за модой тоже нужно следить. Мода это же не плохо, иногда она становится новым стандартом на много лет. За прекрасным пример отставания от моды и стандартов далеко ходить не нужно)
Евгений Шеронов
26 мая 2021, 12:10
0
Не особо слежу за ютуб обучениями, но такой подход — это такой же трэш)

Даже если нужно будет фронтенд раскидать между командами — то это точно будет не так.
Варианты:
1) Разные фреймворки — но по разделам, админка например на одном фреймворке, пользовательская на другом.
2) Если прям хочется поделить одну страницу — то всё просто в пределах одного фреймворка, но использованием одного нормального хранилища с модульной структурой, типо Vuex или Redux. ​

Поэтому, что это видео, что то на английском — всё это жуткий bad practice. Остаётся надеяться, что все просмотревшие восприняли это как учебный эксперимент и никогда не подумают повторять.
Евгений Шеронов
25 мая 2021, 22:56
+2
Минус ставить не буду, так как видно, что за этим стоит большая работа и желание поделиться.

По сути проблемы что здесь, что в других топиках от недостатка опыта.

Чтобы пользователь оформил бесплатный заказ ему достаточно поставить себе одну куку с отрицательной стоимостью доставки)

Куки для таких данных не желательно использовать. Уж лучше писать в сессию и всем управлять на сервере.
Евгений Шеронов
25 мая 2021, 18:12
+1
Я бы сказал, что оно очень необычное))
Полностью смотреть не стал (там на канале ещё 2), но подход автора видео по Vue.js мягко говоря странноват.

Сам компонент вот github.com/jaredfhealy/extrabuilder/ и, наверное, он хорошо выполняет свои функции.
Но автор умудрился намешать ExtJs, Vue.js и даже jQuery и всё это подрубается в админку через iframe!
Евгений Шеронов
24 мая 2021, 11:02
+1
Ну там нет конфликта скриптов точно, а вот в стилях всех у меня добавляется css префикс.

Конфликт будет только с простыми названиями классов, это можно и как плюс использовать. Именно для иконок используются стандартные классы. Но все свои классы я пишу добавляя префикс компонента.

Я в админку совсем не захожу, только после сборки раз в неделю что-то проверить)
По идее всё как видишь на отдельной страничке — так и отображается в админке.

Есть смысл локально развернуть как раз для дебага PHP. Xdebug на modhost не поставить же?
Евгений Шеронов
24 мая 2021, 10:13
+2
Как раз на сервере ничего не происходит, там только MODX который генерирует модели по схеме и отвечает на запросы.
Сборка стилей и js в master ветке локально в шторме. Я их и в git кладу.
Можно и на сервере, в заготовке есть пример сборки assets. Но потом опять надо буде выкачать изменения себе)

Так, уточню про процесс по пунктам подробнее)
1) Открываю PhpStorm
2) Жму serve во вкладке npm (читай пишу npm serve в терминале)
3) Происходит небольшая сборка и становится доступна страничка localhost:8080
4) На этой страничке есть только стили и шрифты от MODX и один
5) В него Vue.js уже маунтит приложение.
6) Для ajax запросов я использую axios, в который в зависимости от окружения добавляются псевдокуки в main.js (там где new Vue(...)) и создание конфига.
import axios from "axios";
   let ym2Config = window.ym2Config || (process.env.NODE_ENV !== 'production' ? {
        modAuth: process.env.VUE_APP_MOD_AUTH || '',
        apiUrl: process.env.VUE_APP_API_URL || '',
        xmlLoaded: true,
        lang: {}
    } : {});
 axios.defaults.baseURL = ym2Config.apiUrl || '/assets/components/yandexmarket2/connector.php';
    axios.defaults.headers.common['modAuth'] = ym2Config.modAuth;
    if (process.env.NODE_ENV !== 'production' && process.env.VUE_APP_COOKIE) {
        axios.defaults.headers.common['modCookie'] = process.env.VUE_APP_COOKIE;
    }
//...тут дальше new Vue({...}).$mount('#yandexmarket-app');
7) И при каждой правке обновляется даже не вся локальная страница, а именно тот участок DOM, что обновился. Vue очень умный) Вся страница обновится если что-то сильно общее поменять.

А чтоб это всё работало админке MODX уже Home контроллер отвечает за создание windows.ym2Config и создание разметки:
<?php 
   ...
// тут ничего нового, всё уже описано в вышеупомянутых заметках про vue в админке)
 public function getTemplateFile(): string
    {
        $this->content .= '<div id="yandexmarket-app"></div>';
        return '';
    }

    public function loadCustomCssJs()
    {
        $this->addCss($this->mgrAssetsUrl.'css/chunk-vendors.css');
        $this->addCss($this->mgrAssetsUrl.'css/app.css');

        $this->addHtml("<script type=\"text/javascript\">
        window.ym2Config = {
            apiUrl: \"{$this->connectorUrl}\",
            modAuth: \"{$this->modx->user->getUserToken($this->modx->context->key)}\",
            xmlLoaded: {$this->xmlLoaded}, 
            lang: {}
        }
        </script>");

        $this->addJavascript($this->mgrAssetsUrl.'js/chunk-vendors.js');
        $this->addLastJavascript($this->mgrAssetsUrl.'js/app.js');
    }
Евгений Шеронов
24 мая 2021, 09:55
+2
Спасибо!)

Интересный подход — нужно попробовать.
В комментах чуть поделюсь кодом:
<?php
// в начале файла /assets/components/yandexmarket2/connector.php
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Headers: Authorization, Cookie, Content-Type, Accept, modAuth, modCookie');
header('Access-Control-Allow-Methods: OPTIONS, HEAD, POST, GET, PUT, DELETE');
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    die; //браузеры уже очень давно перед каждым запросом отправляют OPTIONS для проверки CORS
}
if (isset($_SERVER['HTTP_MODCOOKIE'])) {
    //а тут уже строка в таком формате приходит: "MODSESSID=aaaaa; PHPSESSID=aaaaa"
    $modCookie = array_map('trim', explode(';', $_SERVER['HTTP_MODCOOKIE']));
    foreach ($modCookie as $cookie) {
        list($key, $value) = explode('=', $cookie, 2);
        $_COOKIE[$key] = $value;
    }
}
Этот код у меня только в dev ветке. Людям в продакшн он уже не попадает)

Зачем усложняешь?
Действительно, но в где-то явно может быть иначе. Видел, что вообще по умолчанию PHP 5.4, в /usr/bin/ только один php. А нормальный лежит тут: /opt/php70/bin/php

А для чего такое решение? Чем не устроило то что есть в xPDOSimpleObject например?
Как раз чтобы не привязывать логику к конкретным xPDO объектам. Ну и они не подходят под PSR-4.
Идея была в том, что компонент не должен особо знать, что там подсунуто.
В идеале от этих объектов требовалось имплементация методов save, toArray и get-set для свойств.
Надеюсь, что легко можно будет портировать интерфейс хоть под Laravel, там тоже ActiveRecord модель, которую можно будет смаппить с моделями из компонента)

А еще всегда можно прислать PR
Найду когда-нибудь время и поэкспериментирую с предложенным функционалом, замерю разницу.
Евгений Шеронов
16 мая 2021, 16:22
0
Тут человек AjaxForm путает с AjaxSnippet, поэтому твой совет не поможет (но комментарий привлёк меня, так что косвенно ты тоже помогаешь :))
Там нет никакой формы и вообще ничто никуда не отправится.

При этом сниппет addfavorites ведёт себя как хук для FormIt (хотя вполне себе можно без него, просто оперируя POST данными).

Следовательно вызов в таблице должен быть таким:
(чтобы не мешать синтаксис, ведь люди старались сделать всё изначально на Fenom)
{$_modx->runSnippet('!AjaxForm', [
    'snippet' => 'FormIt',
    'form' => 'tpl.Favorite',
    'hooks' =>  'addfavorite',
    'fi.name' => $service.name,
    'fi.id_service' => $service.id_service,
    'fi.cost' => $service.cost,
    'fi.address' => $service.address
])}
Параметры fi.name и т.д. нужны, чтобы прокинуть данные в форму. См. modx.pro/components/3342

А чанк tpl.Favorite переделать хотя бы так:
<form action="" method="post" class="ajax_form">
    <input type="hidden" name="name" value="[[+fi.name]]">
    <input type="hidden" name="id_service" value="[[+fi.id_service]]">
    <input type="hidden" name="cost" value="[[+fi.cost]]">
    <input type="hidden" name="address" value="[[+fi.address]]">
    <button type="submit" class="center">В избранное</button>
</form>
Это, конечно, не отменяет множество проблем в коде автора.
Например строка $id_user = $modx->user->get('id'); будет работать только для авторизованных пользователей (для админа когда он проверяет). А на пользователях-гостях вполне себе будет падать.

Ну и какой-то странный формат HTML вёрстки с запятой и разными кавычками)
<td class='service' id="cost", value="{$service.price}">Стоимость: {$service.price} ₽</td>

Мне немного страшно и интересно, как же будет выглядеть запрос, который положит данные в базу.
Евгений Шеронов
09 мая 2021, 19:26
0
Почему все так избегают использовать инструменты из коробки?
Есть же хук FormItSaveForm, под который есть даже визуальный интерфейс в админке.
Евгений Шеронов
23 апреля 2021, 14:46
0
Пожалуйста, только тут лучше (float), иначе уже бизнес логика может пострадать))
(int)$_POST['price']
Евгений Шеронов
23 апреля 2021, 13:05
+2
Вроде к каждой статье пишут про безопасность, не?)

$sql = 'SELECT COUNT(id) FROM modxwb_ms2_order_products WHERE product_id = '.$_POST['id'];
Ну это прям призыв, чтобы пришли люди и грохнули сайт без каких-либо сложностей))

$modx->getObject('modResource', $_POST['id']);
И даже так (и вроде когда используется массив) (обсуждали уже где-то здесь) что-угодно можно пропихнуть.

Всегда когда работаем с целыми числами всего лишь нужно добавить (int) перед чем-угодно и спать спокойно.

А это открывает доступ к другим типам инъекций.
<input type="hidden" id="orderid" value="{$.get.msorder}">
Возможно, Fenom что-то там и порежет, но надеяться не стоит.
Евгений Шеронов
23 апреля 2021, 12:54
0
Спасибо!
Теперь по замечаниям.
1) Абсолютный путь в целом там и не нужен, оставлю относительный.
Но ещё более не секьюрно давать кому-то доступ в админку))
Там и без этого никаких проблем получить все системные настройки через Fenom.

2) Поправил, в следующем обновлении уже не должно всплывать.
Евгений Шеронов
13 апреля 2021, 13:35
+1
Авторы могут и не заметить здесь и не знать о запрашиваемых интеграциях)
И в поддержке ни разу про такое никто не спрашивал.

Ну такая интеграция скорее всего потребует дополнительных расходов)

Вообще не помешала бы возможность подключать уведомления об интересующих компонентах, которые всё равно привязываются к топику при их упоминании.
Евгений Шеронов
04 апреля 2021, 13:31
0
А предпросмотр XML работал?
Напишите мне в поддержку с указанием доступов.
По скриншоту тяжело что-то сказать.
Евгений Шеронов
19 марта 2021, 12:28
0
Именно Vuetify 2, иначе бы ещё на несколько месяцев затянул))
Там в целом компоненты очень похожи на Ext JS, разве что гибче. Иконки все используются из MODX стилей.

В первом варианте этой статьи было слишком много технических подробностей, перенёс их в черновик.
Видимо, нужно как нибудь дописать)
Евгений Шеронов
18 марта 2021, 14:02
+4
Я тебе ещё в прошлом году присылал пример встраивания Vue.js в админку))
И вот только сейчас всё это выглядит как полноценный компонент.

Вообще разрабатывать гораздо приятнее и удобнее. Тот же hot-reload, обновляющий на странице только изменившуюся часть DOM, реактивность, роутинг, хранилище, прям хочется ещё что-то сделать)
Но всё равно, полноценный компонент слишком долго делать :(

Если сильно захотеть текущий компонент легко перенести из админки на фронт или вообще заюзать в другой CMS, так как старался абстрагироваться от MODX сущностей (не получилось).
Евгений Шеронов
02 ноября 2020, 15:05
0
Здравствуйте, Вы вроде уже писали мне?

Здесь только через prepareSnippet сможете сделать замену нужных Вам тегов.

Также, если есть какие-то теги или стили у html-тегов, то их нужно подчистить.
Для этого должен быть установлен Jevix.

Вот пример сниппета prepareMarketDescription, который сделает то, что нужно.
Добавьте его и укажите название в настройку ms2ym_prepare_snippet.

<?php
if(!empty($fields['description'])) {
    //масссив для замен 
    $replaces = [
        '[[*pagetitle]]' => $product['pagetitle'],
        '[[+article]]'   => $product['article']
    ];
    
    // все доступные поля можно посмотреть в логе расскоментировав две строки ниже:
    // $modx->log(1,'Поля в XML: '.print_r($fields,1));
    // $modx->log(1,'Поля товара: '.print_r($product,1));
    
    $fields['description'] = $modx->runSnippet('Jevix',[
        'input'=> str_replace(array_keys($replaces), array_values($replaces), $fields['description']),
        'cfgAllowTags'=>'h3,ul,ol,li,p,br',
        'cfgSetAutoLinkMode'=>0,
        'cfgAllowTagParams'=>'{}',
        'cfgSetTagNoAutoBr' => 'ul,ol',
        'cfgSetTagChilds' => '[["ul",["li"],false,true],["ol",["li"],false,true]]',
        'cfgSetTagParamDefault' => '[]',
        'cfgSetTagParamsRequired' => '{}',
        'cfgSetTagNoTypography' => '',
        'cfgSetTagPreformatted' => '',
        'cfgSetTagShort' => 'br'
    ]);
}

return $fields;