Финансовая поддержка VPS, бесплатные дополнения и docs Донаты оплачивают сервер и двигают бесплатные дополнения MODX и документацию. Поддержать

Всего 126 109 комментариев

Денис Усманов
Денис Усманов
Ох Наталья, не просто вам придётся… Разработать свой компонент дело очень не простое! Для этого нужно многое понимать заранее, например структуру данных как минимум, а как максимум старый ExtJS 3.4 для написания интерфейса…

Но, в любом случае, желаю удачи в этом деле!

По идеям, я бы предложил разработать универсальный компонент импорта товаров из файлов формата .xml
Для начала, хотя бы импорт выгрузки Яндекс Маркета.
Олег
Олег
так, а в чем проблема во втором абзаце, не очень понял?
$modx->addEventListenerClosure(
    'OnWebPagePrerender',
    function (\MODX\Revolution\modX $modx) {
        (new \Namespace\YourClass($modx))->doSomething();
        // $class = $modx->services->get('yourservice'); $class->doSomething();
        // \Namespace\YourClass::doSomething();
        // my_global_function($modx);
        return null;
    },
    priority: 10,
    name: 'appendTestComment',
    replace: false
);
Олег
Олег
с обычными плагинами — я пока это не учитывал, но вопрос логичный. НО это не учитывается и в оригинальном методе addEventListener, так что текущая логика по сути не меняется. Оригинал:
public function addEventListener($event, $pluginId, $propertySetName = '') {
        $added = false;
        $pluginId = intval($pluginId);
        if ($event && $pluginId) {
            if (!isset($this->eventMap[$event]) || empty ($this->eventMap[$event])) {
                $this->eventMap[$event]= [];
            }
            $this->eventMap[$event][$pluginId]= $pluginId . (!empty($propertySetName) ? ':' . $propertySetName : '');
            $added = true;
        }
        return $added;
    }
Проблема в том что карта у них строится без какой либо доп информации о плагинах, просто событие->список ID плагинов, уже отсортированных в sql запросе. То есть пересортировать ее без дополнительного запроса к базе не получится (ну или надо сохранять расширенную карту из базы при инициализации и потом при добавлении нового плагина пересобирать итоговую карту). Сейчас реализовано так, что сначала выполняются плагины из бд — и подвязанные к событию в админке, и подвязанные к событию в коде, потом все closure плагины. Вообще это больше не для того чтобы кто-то в админке вручную тыкал, а чтобы например при разработке пакета вы спокойно свой функционал раскидали по нужным событиям и не парились с созданием плагинов и привязкой/отвязкой событий при обновлении например.
Артур Шевченко
Артур Шевченко
Я имел ввиду как управлять порядком выполнения, если плагины принадлежат разным компонентам? Сейчас открыл список плагинов и перетасовал приоритеты как надо, а тут списка плагинов не будет. Как искать какие плагины срабатывают на то или иное событие? Как менять их порядок?

И после просмотра примера возник новый вопрос: а если у меня будет большая функция или несколько функций или я хочу использовать целый класс в плагине, как тогда?
Наумов Алексей
Наумов Алексей
Но вообще выглядит прикольно. Прям клево, взять и подписаться на событие в своем коде без создания плагинов — удобно должно быть.
Наумов Алексей
Наумов Алексей
Вижу в примерах на git что есть параметр priority:
$modx->addEventListenerClosure(
    'OnWebPagePrerender',
    function (array $params, \MODX\Revolution\modX $modx) {
        $output = &$modx->resource->_output;
        $output .= "\n<!-- TEST CLOSURE: " . date('Y-m-d H:i:s') . " -->";
        return null;
    },
    priority: 5,
    name: 'appendTestComment'
);
видимо, управлять приоритетом можно.
Артур Шевченко
Артур Шевченко
Что делать если нужно изменить порядок выполнения плагинов? Если будет использоваться смешанный режим плагинов: твой + стандартный — в каком порядке будут выполняться плагины, особенно если у них одно событие?
Артур Шевченко
Артур Шевченко
Александр Туниеков
Александр Туниеков
К сожалению, не понимая думаю можно наделать других дырок. Попробовал проверить на уязвимость из https://habr.com/ru/articles/130826/ .

Вроде не уязвимо :-). Почти все через pdoFetch идет. Только иногда использую сложное условие вроде (id IN (2,3) and (parent = 4 or parent IS NULL)) в where. Тогда… хм. проверю :-).

Код для проверки:
<?php
$pdo = $modx->getService('pdoFetch');
$id = $_GET['id'];
$pdo->setConfig([
    'class'=>'modResource',
    'where'=>[
        0=>"(id = $id and (parent = 4 or parent = 0))"
    ],
    'limit'=>0,
    'return'=>'data'
]);

$ress = $pdo->run();
foreach($ress as $res){
    echo "<p>{$res['id']}</p>";
}
echo '<pre>'.$pdo->getTime().'</pre>';
На запрос gettables.ru/test.html?id=4+OR+1 выдало:
1

2

3

4

5

6

7

14

16

19

20

21

22

25

30

0.0000529: xPDO query object created
0.0000019: Processed additional conditions
0.0000720: Added where condition: 0=(id = 4 OR 1 and (parent = 4 or parent = 0))
0.0000749: Sorted by modResource.id, ASC
0.0002530: SQL prepared "SELECT * FROM `modx_site_content` AS `modResource` WHERE (id = 4 OR 1 and (parent = 4 or parent = 0)) ORDER BY modResource.id ASC "
0.0014510: SQL executed
0.0000789: Rows fetched
0.0000720: Returning raw data
0.0167792: Total time
4 194 304: Memory usage
Выдало все id страниц. То есть
'where'=>[
        0=>"(id = $id and (parent = 4 or parent = 0))"
    ],
Уязвимо для инъекций. Будем знать.