Артем

Артем

С нами с 15 октября 2017; Место в рейтинге пользователей: #168
Василий Наумкин
19 сентября 2019, 08:10
3
+4
Другой вариант, который уже больше подходит для концепции REST — отсылаем все запросы как и договаривались на адрес по маске /api/**/*
MODX предсказуемо выдаст событие onPageNotFound — ну а дальше как завещал @Василий Наумкин выстраиваем плагин маршрутизации — и делаем что захотим.
Это если решать все вопросы одним MODX. Да и тогда лучше использовать OnHandleRequest.

А так, лично я давно всё отправляю через Nginx:
location ~ ^/api/ {
    rewrite ^/api/(.*)$ /api.php?q=$1;
}
И там уже любые маршруты с контроллерами.
Василий Наумкин
26 ноября 2018, 07:29
6
+4
У меня все письма перед отправкой проходят через pelago/emogrifier — так что на расхождений в отображении почти нет.

Грузим свой почтовый класс раньше всех:
$modx->getService('mail', 'extraMail', 'path/to/class');

А в классе extraMail добавляем свою обработку:
<?php
if (!class_exists('modPHPMailer')) {
    /** @noinspection PhpIncludeInspection */
    require MODX_CORE_PATH . 'model/modx/mail/modphpmailer.class.php';
}

class extraMail extends modPHPMailer
{
    /** @var PHPMailer $mailer */
    public $mailer;
    
    /**
     * @param string $key
     * @param mixed $value
     */
    public function set($key, $value)
    {
        if ($key == modMail::MAIL_BODY) {
            $emogrifier = new \Pelago\Emogrifier($value);
            $value = $emogrifier->emogrify();
            $this->set(modMail::MAIL_BODY_TEXT, $this->mailer->html2text(nl2br($value)));
        }
        parent::set($key, $value);
    }
Руслан Касимов
28 марта 2018, 20:01
2
0
Спасибо) Шрифт Montserrat
Илья Уткин
20 марта 2018, 16:07
2
0
Создать свой приватный репозиторий и разместить пакет в нём.

Василий Наумкин
14 декабря 2016, 12:43
2
+3
500 000 страниц сайта — это нормально. А вот 500 000 ресурсов — совершенно нет, MODX к такому не готов.

Разница в том, что ресурсы нужны для разделов сайта, служебных страниц и всего такого. Если же сайт продаёт полмиллиона товаров или содержит объявления — нужно это выносить в отдельные таблицы, с нужными колонками и индексами.

Например, вот я делал vrmedia.tv. Ресурсов в дереве там меньше 50, а фоторепортажей и картинок многие тысячи. Всё летает, лайкается, добавляется в избранное — и хранится в отдельных таблицах.

В таком направлении и нужно двигаться, используя MODX как удобную обёртку для своих данных.
Константин Ильин
16 ноября 2016, 19:55
2
+2
Чтож, уже ноябрь, но лучше поздно чем никогда)

Спасибо Сергей Шлокову, он на пальцах мне обьяснил что так как я хотел сделать выше — нельзя.
Последовательность такая:
1. Нажимается кнопка.
2. В функции кнопки вызывается ajax запрос к процессору который выдает поля.
3. Только когда ajax выполнился вызывается окно. В вызов окна сразу подсовываются готовые поля, сформированные из ответа ajax.

Код функции процессора — process ()
public function process()
    {
        /*некий код*/
	$fields = '';
        // Существует какая то некая таблица в которой 1 строка это поле
        $table = $this->modx->getTableName('FieldsItems');
        $query = $this->modx->query("SELECT * FROM ".$table." WHERE active = 1");
	
        if (!is_object($query)) {
           
           return $this->failure($this->modx->lexicon('fl_data_err_get_field'));

        }else{

           $arr = $query->fetchAll(PDO::FETCH_ASSOC);

           foreach ($arr as $value) {

               $fields[] = array(
                    'xtype' => 'textarea',
                    'fieldLabel' => $value['name'],
                    'name' => "fl-".$value['code'],
                    'id' => 'ext-gen-fl-'.$value['code'],
                    'anchor' => "99%",
                    'allowBlank' => "false",
                    'value' => $fieldsValues[$value['code']] 
                );
           }

        }
        return $this->success('',$fields); // Возвращаем массив полей
    }

Как это в EXT.JS. Тут два запроса ajax, первый получает поля, второй к процессору get который выдает данные об объекте.
MODx.Ajax.request({
            url: Fl.config.connectorUrl
            ,params: {
                action: "mgr/data/get_fields", // Тот самый процессор который выдает поля
                id_res: MODx.request.id,
            }
            ,listeners: {
                success: {fn: function(res) {
                    
                    var fieldsArr = res['object']; // Ответ от процессора с полями, он возвращает массив с данными полей
                    fieldsArr = fieldsArr || {}; 
                    MODx.Ajax.request({
                        url: this.config.url,
                        params: {
                            action: 'mgr/data/get',
                            id: MODx.request.id,
                        },
                        listeners: {
                            success: {
                                fn: function ( r ) { 
                                   
                                    var w = MODx.load({
                                        xtype: 'fl-data-window-update',
                                        id: Ext.id(),
                                        addFields: fieldsArr, // Здесь передаем поля в вызов окна
                                        record: r,
                                        listeners: {
                                            success: {
                                                fn: function () {
                                                    this.refresh();
                                                }, scope: this
                                            },
                                            hide: {
                                                fn: function () {
                                                    setTimeout(function(){w.destroy();},200);
                                                }, scope: this
                                            }
                                        }
                                    });
                                    w.reset();
                                    w.setValues(r.object);
                                    w.show(e.target);
                                }, scope: this
                            }
                        }
                    });
                }, scope: this}
            }
        });

В extende окна:
Ext.extend(Fl.window.UpdateItem, MODx.Window, {

    getFields: function (config) {
        return [{
            xtype: 'hidden',
            name: 'id',
            id: config.id + '-id',
            value: config.id
        },{
            xtype: 'xcheckbox',
            boxLabel: _('fl_lang_active'),
            name: 'active',
            id: config.id + '-active',
            checked: true,
        },
            config.addFields   // ВОТ ТУТ И ДОБАВЛЯЮТСЯ ПОЛЯ, т.е. тот массив полей который передали в ajax запросе
        ];
    },

    loadDropZones: function () {
    }

});
Ext.reg('fl-data-window-update', Fl.window.UpdateItem);
Как то так, наверняка посмотрев через год на этот код будет такая мысль:
«Под чем я был кода писал этот код»
Василий Наумкин
07 сентября 2016, 10:52
1
0
Потому, что автор этих дополнений использует 2 разных события для одной цели, вместо того, чтобы использовать верное событие в обоих плагинах — msOnGetProductPrice.

Если что, у событий плагинов есть приоритет и одно событие можно использовать хоть в 100 плагинах, тогда изменение цены пройдёт по цепочке от низшего приоритета к высшему.
Василий Наумкин
06 сентября 2016, 10:40
3
+1
Ну тогда rewrite должен решить все твои проблемы.
location ~* ^/en/assets/images/ {
    rewrite	^/en/assets/images/(.*)    /assets/images/$1 permanent;
}

Кстати, можно сделать еще круче — без редиректа, а просто подставляя нужную директорию, вот так:
location ~* ^/en/assets/images/(.*) {
    alias /полный_путь_к_файлам_от_корня_сервера/assets/images/$1;
}
Василий Наумкин
24 марта 2016, 07:44
8
+2
Лично я закрываю служебные директории через веб-сервер на случай обнаружения новой уязвимости в MODX.

Например, как это было, когда движок некорректно обрабатывал запросы в несуществующий контекст в коннекторах. Там еще одна PHP авторизация не помогла бы, так как хакер получал доступ к API через обычные GET запросы к определённому файлу.

Именно поэтому я закрываю для доступа снаружи и админку, и коннекторы, и ядро. Причём, не через потенциально уязвимый движок, а средствами гораздо менее потенциально уязвимого Nginx.
location ~* ^/(core|manager|connectors)/ {
    auth_basic "Restricted Access";
    auth_basic_user_file /home/site/.htpasswd;
    try_files               $uri $uri/ @rewrite;
    location ~ \.php$ {
            include         fastcgi_params;
            fastcgi_param   SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_pass    backend-site;
    }
}

А зачем нужна вот эта инструкция — большой вопрос.
Fi1osof
07 января 2016, 11:57
20
+12
Если ключ не хотите светить, то однозначно запрос надо слать с вашего сервера на донора. В MODX есть готовый CURL-клиент. Вот код для примера:
$client = $modx->getService('rest.modRestCurlClient');
$result = $client->request('https://ya.ru', '/', 'POST', $params = array('foo'  => 'foo'));
print $result;
Можете с этим кодом к консоли поиграться.