Всего 123 782 комментария

Кирилл
13 ноября 2023, 14:26
0
Вот мое решение, может сразу упросит поиск по поводу datetime
Данные в БД храню в integer формате в unixtimestamp
Мне важно получить дату до какого времени оплачен доступ у юзера, потому условно дата 01/01/2023, то сохраняю 01/01/2023 23:59:59 (GMT+0000)
Ну и соответственно потом показываю по разному данную дату (в подписи к полю — в привычном порядке для СНГ — день/месяц/год), а в самом поле, как по умолчанию месяц/день/год.
И да, для сохранения заюзал еще одно системное событие OnBeforeUserFormSave

<?php
/* userFields */
switch ($modx->event->name) {
    case "OnMODXInit":
        $map = array(
            'modUserProfile' => array(
                'fields' => array(
                    'surname' => '',
                    'patronymic' => '',
                    'paid' => '',
                ),
                'fieldMeta' => array(
                    'surname' => array(
                        'dbtype' => 'varchar',
                        'precision' => '100',
                        'phptype' => 'string',
                        'null' => false,
                        'default' => '',
                    ),
                    'patronymic' => array(
                        'dbtype' => 'varchar',
                        'precision' => '100',
                        'phptype' => 'string',
                        'null' => false,
                        'default' => '',
                    ),
                    'paid' => array(
                        'dbtype' => 'int',
                        'precision' => '10',
                        'phptype' => 'integer',
                        'null' => true,
                        'default' => null,
                    ),
                ),
            ),
        );

        foreach ($map as $class => $data) {
            $modx->loadClass($class);
            foreach ($data as $tmp => $fields) {
                if ($tmp == 'fields') {
                    foreach ($fields as $field => $value) {
                        foreach (array('fields', 'fieldMeta', 'indexes') as $key) {
                            if (isset($data[$key][$field])) {
                                $modx->map[$class][$key][$field] = $data[$key][$field];
                            }
                        }
                    }
                } elseif ($tmp == 'composites' || $tmp == 'aggregates') {
                    foreach ($fields as $alias => $relation) {
                        if (!isset($modx->map[$class][$tmp][$alias])) {
                            $modx->map[$class][$tmp][$alias] = $relation;
                        }
                    }
                }
            }
        }

        break;

    case "OnUserFormPrerender":
        if (!isset($user) || $user->get('id') < 1) {
            return;
        }

        if (!$modx->getCount('modPlugin', array('name' => 'AjaxManager', 'disabled' => false))) {
            $data['surname'] = htmlspecialchars($user->Profile->surname);
            $data['patronymic'] = htmlspecialchars($user->Profile->patronymic);
            $data['paid'] = date('m/d/Y', htmlspecialchars($user->Profile->paid));
            $dateRus = date('d.m.Y', htmlspecialchars($user->Profile->paid));

            $modx->controller->addHtml("
                <script type='text/javascript'>
                    Ext.ComponentMgr.onAvailable('modx-user-tabs', function() {
                        this.on('beforerender', function() {
                            var leftCol = this.items.items[0].items.items[0].items.items[0];
                            var rightCol = this.items.items[0].items.items[0].items.items[1];

                            leftCol.items.insert(4, 'modx-user-surname', new Ext.form.TextField({
                                id: 'modx-user-surname',
                                name: 'surname',
                                fieldLabel: 'Фамилия',
                                xtype: 'textfield',
                                anchor: '100%',
                                maxLength: 255,
                                value: '{$data['surname']}',
                            }));

                            leftCol.items.insert(5, 'modx-user-patronymic', new Ext.form.TextField({
                                id: 'modx-user-patronymic',
                                name: 'patronymic',
                                fieldLabel: 'Отчество',
                                xtype: 'textfield',
                                anchor: '100%',
                                maxLength: 255,
                                value: '{$data['patronymic']}',
                            }));

                            rightCol.items.insert(0, 'modx-user-paid', new Ext.form.DateField({
                                id: 'modx-user-paid',
                                name: 'paid',
                                fieldLabel: 'Оплачено ДО конца этой даты rus: {$dateRus}',
                                xtype: 'datetime',
                                format: 'm/d/Y',
                                value: '{$data['paid']}',
                            }));

                        });
                    });
                </script>
            ");
        }

        break;

    case "OnBeforeUserFormSave":
        $user->Profile->set('surname', $_POST['surname']);
        $user->Profile->set('patronymic', $_POST['patronymic']);
        $user->Profile->set('paid', strtotime($_POST['paid'].' 23:59:59'));

        break;
}
Алексей
13 ноября 2023, 13:29
0
Разобрался. Спасибо!
Баха Волков
13 ноября 2023, 13:26
0
Указывать нужно либо modx, либо fenom
Алексей
13 ноября 2023, 13:02
0
Баха, а подскажите пожалуйста, как сделать синтаксис как у вас на фото. Не выходит.
Прописал вот так:
"files.associations": {
      "*.tpl": "html | modx | fenom"
    }
Работает либо одно, либо другое.
Павел Голубев
13 ноября 2023, 12:09
+1
Vue/React не делают шаг назад. Добавили серверного рендеринга, чтобы банально быстрее грузилось, чтобы пользователь быстрее мог увидеть интерфейс, а не белый лист с индикатором загрузки.

Проблемы с расширяемостью готовых Vue/React/Svelte компонент действительно существует, проблема не решается в лоб. Но об этом знает любой front-end разработчик с релевантным опытом.
Алексей
13 ноября 2023, 11:42
+1
Добрый день!
Спасибо за проделанную работу! Очень нужное дополнение. Донат отправил.
Arahort
13 ноября 2023, 10:59
+1
Респект, хоть и пользуюсь phpStorm)
Andrei
13 ноября 2023, 10:50
0
На страницах-символичеких ссылках не работает
Павел Гвоздь
13 ноября 2023, 10:38
0
Тут решение. Пишите в ТП на Модстор в следующий раз.
Баха Волков
13 ноября 2023, 09:49
+4
Спасибо товарищ за теплые слова, они зачастую бывают важнее всего остального
Семён Кудрявцев
13 ноября 2023, 09:36
+5
Очередной крик души)
Мне знакома твоя ситуация, я сам был в ней 2 года назад и вот к чему пришел в итоге поисков я:
  • MODX, действительно, скажем честно, вряд ли ожидает новый взлет популярности — всему причина нежелание разработчиков кардинально менять движок, но с другой стороны он как решал прекрасно свои задачи 10 лет назад так и решает их сейчас. Если Web-мастеру становится тесно с ним жить, то значит он перерос этот движок, что хорошо на пути развития как специалиста.
  • Куда двигаться дальше? Мой путь: Laravel, Spiral Freamework — просто «миллиарднократный» скачок в плане Developer Experience, всё по полочкам, всегда знаешь где, когда и откуда растут ноги у малейшей ошибки в коде, мониторинг запросов и ещё куча всего всего, просто на голову выше качество кода самих фреймворков — есть чему учиться.
  • PHP или Nodejs — бесспорно нода за последние годы выросла и на ней можно реально делать хорошие, сложные проекты, но мне гораздо легче оставаться в рамках знакомого языка, который полностью покрывает потребности проектов, что мне достаются. И тут замечу, что php умеет обрабатывать js на стороне сервера, а то меня это смутило как-то в твоем крике души, вопрос лишь гугления. Если просмотреть внимательно тенденцию реактивных фреймворков — до них всех начало доходить, что всё делать на клиенте не самый лучший путь, отсюда как грибы у всех начали появляться Server Actions — многие «старики» даже ржут с этого, так как по сути эти «реактивисты» возвращаются к тому же с чего уходили, то есть к серверному рендерингу, просто с последующей гидратацией. С другой стороны классические движки наоборот переняли многое от реактивщины и сегодня можно комфортно писать привычные шаблоны на бекенде прямо в виде SFC как например во Vue и это всё уедет на клиент отрендеренное. Хороший обмен опытом между двумя путями.
  • Ну и чуть приближенней к твоей задаче из моего личного опыта: такие вещи как CRM и ERP системы нужно писать на очень зрелых технологиях, проверенных временем и как правило такие системы пишутся и состоят из 2 частей отдельный проект API, и отдельный проект это клиентские приложения, на чем бы они не были написаны. Сегодня ты делаешь сайт, завтра понадобится мобильное приложение под android и под ios, а послезавтра уже десктопный софт на винду и macos. Когда есть API с хорошей документацией, развивать проект гораздо удобнее и легче. ERP это один из самых сложных по структуре проект из всех что мне доводилось встречать, куча асинхронщины, что многих php-шников сразу вводит в ступор, но тут появляется Spiral Framework — чудо мутант PHP + GO, целью которого как раз являются такие вот сложные, многослойные проекты, вот собственно его я и выбрал и подробно в нем копаюсь последний год, пока впечатления только положительные.
Александр
13 ноября 2023, 09:31
0
Именно, вам не повезло или вы так специалистов выбирали. Например, не могу порекомендовать себя на данный момент в этом стеке, т.к. сам учусь в процессе.

Сколько людей, столько и мнений, возможно, вам этот подход не подходит, а может не разобрались толком, а может используете не там, где надо, а может «спецы» такие и т.д. Есть масса задач, для которых CMS подходят куда лучше, ибо нечего велосипед изобретать, а есть такие, реализуя которые на CMS сталкиваешься с массой сложностей и ограничений. Василий отлично описал это в статье, упомянутой выше в комментарии. В мире MODx — это ExtJS, это конфликтующий сам с собой Composer (а точнее разные версии дополнений, необходимые для разные дополнений) и т.д. Сравните реализацию одного и того же на Vue и ExtJS.

Такая компания, как Сбер, наприимер, использую не по наслышке React, не жалуется ?

Ух, где же Вы, Николай Ланец, вас в этом обсуждении очень не хватает :)
Александр Мельник
13 ноября 2023, 09:15
+1
нет слов, вы большой молодец.
Николай Савин
13 ноября 2023, 09:10
+12
Со стороны представителя сообщества хочу сказать огромное спасибо тебе Баха. Ты большой молодец. На полном энтузиазме, не прося ничего в замен, не хвастаясь (ну ладно чуть чуть среди своих) — проделал огромную работу. Кто не в курсе Баха занимался этим наверное полгода, периодически показывая нам в закрытой группе небольшие кусочки проделанной работы.

Друзья, вот именно на такие заметные проекты, ускоряющие вашу собственную работу и идут донаты.
Мы от коллектива поощряем нашего друга на сумму 20 000 рублей. Но хотелось бы выделить больше.
Потому в очередной раз призываю вас всех поддержать копеечкой сообщество или лично Баху для дальнейшего развития.
Все реквизиты сообщества можно посмотреть здесь
Александр Мельник
13 ноября 2023, 09:07
+2
Могу высказать свое, личное и не объективное мнение.
Считаю что даже в 2023 году ни node ни vuejs все еще не доросли до такого уровня, чтобы их использовать как основной стек для крупных, серьезных проектов. К самой ноде особых притензий нет, но поскольку она всегда идет в связке с каким то vuejs или react то и говорю о них как об едином целом.
Почему я так говорю. Ну во первых из последнего опыта. Долгие годы работали с классическим стеком технологий для веба, последние два проекта решили делать «модными». Тем более что это были закрытые crm системы и там не нужно было думать о сео и как следствие о ssr.
Наняли специально фронтендщиков, которые в грудь себя били что ничего лучше vuejs в мире не бывает и что они любую задачу там решат. И что в итоге — полный провал по всем срокам, все задачи выполняются в 4-10 раз дольше. Постоянные проблемы с тем, что никто не хочет писать ничего своего, все из готовых vue компонентов собирается и оказалось, что сложные вещи делать на vue очень сложно. Все привыкли какой-то туду лист по примерам сделать и считают что все — теперь на vuejs могу любой сложности проекты делать. А потом приходит заказчик, говорит, мол отличная таблица с данными, только встройте в нее такой то функционал и вот такой то, разработчики пытаются один готовый компонент впихнуть в другой, возникает кучу проблем. Короче говоря, то, что я могу сделать на чистом js/html/css за день (при условии что я бекендщик) на vue занимает недели. А учитывая, что заказчик очень переменчивый и может каждый день менять решения, то внести визуальные и логические изменения становится нашим фронтендищикам все сложнее и сложнее.
Можно и нужно конечно сказать, что это нам так не повезло, что мол есть фронтендщики которые делают любой сложности задачи и быстро. Может и есть, но у нас это уже третий опыт, третья попытка нанять опытных фронтедщиков и третий раз она заканчивается полным срывом сроков.
Но это мой опыт, но есть и другие звоночки, что сама идея современного фронтенда (рендеринг на клиенте) не была гениальной и может в скором времени быть признана неперспективной. Видели новый next.js? В нем разработчики делают шаг назад и постепепенно отказываются от рендеринга на фронте. видео
Мой вывод (очень субъективный) — на 2023 год vuejs все еще интересный, но не продакшен реди инструмент, на котором легко делать простые вещи (туду лист и прочее) но сложно и долго делать сложные вещи.
Александр
13 ноября 2023, 09:07
+3
Доброго времени суток ✌

Думаю, как и многие здесь, начал разработку сайтов благодаря курсам, заметкам и пакетам, созданными @Василий Наумкин. Лично я стал зарабатывать первые деньги именно благодаря MODx и Василию. Дай Бог Вам здоровья! ?

Сейчас же, Василий создал несколько курсов (в данный момент в бесплатном доступе на bezumkin.ru) по своей новой системе VESP: Vue + Eloquent + Slim + Phinx. Статьи, где упомнут такой выбор стека, к сожалению, не нашёл, помню, что выбор пал из-за того, что PHP хорошо знаком (мягко говоря) и переход на более современные тенденции более плавный. Мне эта идея понравилась и, изучая курсы, стал сразу работать над новым проектом, используя новую систему. Легче задышалось! Вы сами выбираете, где и что как должно работать, система вас не ограничивает! Рекомендация к прочтению: bezumkin.ru/sections/projects/3075
Понимаю, что создание того же (а именно агрегатор для бань с календарем и массой нестандартных решений) на MODx, несмотря на имеющийся Agenda, котрый покрывал 80% моих задач, был бы сплошной мукой. Даже простые вещи, как например, доабвить в календарь вывод номера телефона, ведь пришлось бы править исходники или выдумыать, как инетгрироваться в пакет без правок.

API на PHP, причём некотрые вещи, типо миграций и управление базой данных идентичны Laravel, а он в свою очередь имеет огромное сообщество, дополнения, инструкции и т.д. А управление фронтендом перенеслось на Vue + Nuxt для серверного рендера.
Выбор стека может быть любым: будь то полный переход на JS, как вы описали, или же React + дополения для роутинга и т.д. Vue — фреймворк, React — библиотека, и разница в том, что во Vue и Nuxt за вас уже решили (стандартизировали, можно сказать) структуру и архитектуру, не нужно придумывать велосипед. В React же выбор остается за программистом и стек может быть очень разным, как структура проекта, так и используемые технологии. Думаю, многие оценили прелести линтеров и преттиеров для js. Бесят, но зато разбираться в своем/чужом коде, оформленным по определенным правилам, куда проще ?

Выбор за вами :) Если полный переход на JS вас не пугает, как совершенно новое, чему придётся учиться с нуля — вперёд, всё получится! ?
Александр Туниеков
13 ноября 2023, 07:39
0
Ок. Посмотрим на реализацию :-)
Артур Шевченко
13 ноября 2023, 07:03
0
Начнем с того, что mfilter хоть и оптимальное решение, но сама схема таблиц такова, что при большом количестве товаров, даже с отключённой агрегацией, фильтры работают медленно. Кстати в моем компоненте агрегации нет, я ей никогда не пользовался и практический смысл её весьма сомнительный, но не суть. Ничего гениального я не придумал, принцип работы остался тем же: выбираем по каким полям фильтровать, выводим эти поля на фронт фильтруем. Разница только в том, что значения для фильтрации заранее собираются в отдельную таблицу(для маленьких сайтов) или в несколько таблиц(для больших). Что касается раздувания БД, то в текущей реализации у меня к 100К товаров 170К индексов(так я называю собранные для фильтрации данные). Если злоупотреблять опциями с множественным выбором, то можно конечно таблицу раздуть знатно. Опять же, это уже вторая версия, в первой индекс строился иначе, и там в БД было больше миллиона записей, однако запросы отрабатывали менее чем за 1сек, и если бы не проблема с невозможностью фильтрациии по множественным знаниям, я бы схему индексации менять не стал.