Проблема следующая: написал плагин, который синхронизирует ветки ресурсов, если создается или редактируется ресурс в 1ой ветке (id родительского ресурса 104 в листинге), то создается в этом же месте почти такой же ресурс, но msProduct или msCategory в другой ветке каталога товаров minishop. повесил на плагин 2 события — onDocFormSave и OnDocFormDelete. Поставил условие, при котором плагин срабатывал бы только для ресурсов 1ой ветки. Плагин работает отлично при редактировании, создании или удалении ресурсов, если эти действия проделываешь с ресурсами 1ой ветки, но если пытаешься сохранить другой ресурс, не связанный с этими двумя ветками, начинается бесконечная загрузка (сохранение), тем не менее изменения сохраняются после обновления страницы. Ниже листинг.

<?php
switch ($modx->event->name) {
case 'OnDocFormSave':
$resid = $resource -> get('id');
$parent = $resource -> get('parent');
$parentclass = $modx -> getObject('modResource', $parent) -> get('class_key');
$treeArray = $modx -> getChildIds(104, 100, array('context' => 'web'));
if(!in_array($resid, $treeArray)) {
$resource -> set('longtitle', $rid);
$resource -> save();
break;
}
if($parentclass == 'CollectionContainer') break;
$collection = $modx -> getCollection('modResource', array('parent' => 104));
$resource -> set('template', 14);
$resource -> set('hidemenu', 1);
$resource -> save();
$restemp = $resource -> get('template');
$resourceid = $resource -> get('id');
$courses = $modx -> getCollection('modResource', array('parent' => 4));
$parenttitle = $modx -> getObject('modResource', $parent) -> get('pagetitle');
$i = 0;
$path = [];
function searchTree($item) {
global $modx, $i, $path;
$parentid = $item -> get('parent');
if($parentid != 104) {
$parent = $modx -> getObject('modResource', $parentid);
$parenttitle = $parent -> get('pagetitle');
$path[] = $parenttitle;
searchTree($parent);
$item -> set('longtitle', 'ok');
$item -> save();
return $path;
}
}
function createSavedRes($r, $prods, $res, $title) {
global $modx;
$rid = $r -> get('id');
$restitle = $r -> get('pagetitle');
$isfold = $r -> get('isfolder');
$parent = $r -> get('parent');
$status = $r -> get('published');
$rclass = $r -> get('class_key');
if($rclass ==«CollectionContainer») {
$rprice = $r -> getTVValue('price');
}
$ptitle = $modx -> getObject('modResource', $parent) -> get('pagetitle');
foreach($prods as $key => $value) {
$prodid = $prods[$key] -> get('id');
$prodtitle = $prods[$key] -> get('pagetitle');
for($i = 0; $i < count($res); $i++) {
if ($prodtitle == $res[$i]) {
if($prodtitle == $ptitle) {
if($rclass==«CollectionContainer») {
$newProd = $modx -> newObject('msProduct');
$newProd -> set('price', $rprice);
} else {
$newProd = $modx -> newObject('msCategory');
}
$newProd -> set('template', 10);
$newProd -> set('parent', $prodid);
$newProd -> set('pagetitle', $restitle);
$newProd -> set('alias', $rid);
$newProd -> set('published', $status);
$newProd -> save();
} else {
createSavedRes($r, $modx -> getCollection('modResource', array('parent' => $prodid)), $res, $title);
}
}
}
}
}
function editSavedRes($r, $prods) {
global $modx;
$rid = $r -> get('id');
$restitle = $r -> get('pagetitle');
$rclass = $r -> get('class_key');
$isfold = $r -> get('isfolder');
$parent = $r -> get('parent');
$status = $r -> get('published');
$ptitle = $modx -> getObject('modResource', $parent) -> get('pagetitle');
if($rclass ==«CollectionContainer») {
$rprice = $r -> getTVValue('price');
}
foreach($prods as $key => $value) {
$prodid = $prods[$key] -> get('id');
$prodalias = $prods[$key] -> get('alias');
if($prodalias == $rid) {
$prods[$key] -> set('pagetitle', $restitle);
if($rclass==«CollectionContainer») {
$prods[$key] -> set('class_key', 'msProduct');
$prods[$key] -> set('price', $rprice);
} else {
$prods[$key] ->set('class_key', 'msCategory');
}
$prods[$key] ->set('template', 3);
$prods[$key] -> set('published', $status);
$prods[$key] -> save();
} else editSavedRes($r, $modx -> getCollection('modResource', array('parent' => $prodid)));
}
}
$path = searchTree($resource);
if(count($path)) {
$reversepath = array_reverse($path);
} else {
$modx->log(MODX_LOG_LEVEL_ERROR, 'error, path is not finded');
}
if ($mode == 'new') {
createSavedRes($resource, $courses, $reversepath, $ptitle);
} else {
editSavedRes($resource, $courses);
}
break;
case 'OnDocFormDelete':
function deleteSavedRes($r, $prods) {
global $modx;
$rid = $r -> get('id');
$restitle = $r -> get('pagetitle');
foreach($prods as $key => $value) {
$prodid = $prods[$key] -> get('id');
$prodtitle = $prods[$key] -> get('pagetitle');
$prodalias = $prods[$key] -> get('alias');
if($prodalias == $rid) {
$prods[$key] -> remove();
$r -> $remove();
} else deleteSavedRes($r, $modx -> getCollection('modResource', array('parent' => $prodid)));
}
}
$resid = $resource -> get('id');
$treeArray = $modx -> getChildIds(104, 100, array('context' => 'web'));
if(!in_array($resid, $treeArray)) return;
$products = $modx -> getCollection('modResource', array('parent'=> 4));
deleteSavedRes($resource, $products);
break;
}