| Новости | FAQ | Авторы | Документация | В действии | Библиотека |
| Инструменты | Полезные ссылки | Хостинги | Скачать | Примеры | Форум |
Pa1n 18.09.2005 21:13
В продолжении к http://www.parser.ru/forum/?id=44562#################################################################################################
# грузит + кеширует + процессит + исполняет код обработчика
@prepareProcesess[dataProcessID][dataProcessMain;dataProcessFileName;dataProcessFile;dataProcessBody]
# обработчик может быть еще не загружен
^if(!$PROCESSES.[$dataProcessID].processBodyLoaded){
# замена имени @main[...] обработчика
$dataProcessMain[process_${dataProcessID}_main]
^try{
# полный путь до обработчика
$dataProcessFileName[${SYSTEM.processDir}$PROCESSES.[$dataProcessID].filename]
$dataProcessFile[^file::load[text;$dataProcessFileName]]
# тело обработчика
$dataProcessBody[^taint[as-is][$dataProcessFile.text]]
# компиляция обработчика в текущем (класс engine) контексте
^process{@${dataProcessMain}^[blockParam^;blockBody^]
$dataProcessBody}[
# $.main[$dataProcessMain]
$.file[$dataProcessFileName]
]
# добавление информации в хеш о main dataProcess
$PROCESSES.[$dataProcessID].main[$$dataProcessMain]
}{
# что-то случилось при чтении и компиляции
# для использования в debug целях закомментировать
$exception.handled(1)
}
# в любом случае сохранить, что была предзагрузка
# никогда не приведет к повторной компиляции обработчика
$PROCESSES.[$dataProcessID].processBodyLoaded(1)
}
#end @prepareProcesess[]
#################################################################################################
# запуск обработчиков объектов
# в принципе, то-же самое что executeBlock, но обработчику объекта может сваиться от передачи ему пустых параметров :)
@executeProcess[dataProcessID]
# подготовка обработчика к использованию
^prepareProcesess[$dataProcessID]
# запуск обработчика
^if($PROCESSES.[$dataProcessID].main is junction){
# запуск обработчика
$result[^PROCESSES.[$dataProcessID].main[]]
}{
# нужно убрать кактус с подоконника
$result[]
}
#end @executeProcess[]
#################################################################################################
# запуск обработчиков блоков
@executeBlock[dataProcessID;blockParam;blockBody]
# подготовка обработчика к использованию
^prepareProcesess[$dataProcessID]
# запуск обработчика
^if($PROCESSES.[$dataProcessID].main is junction){
$result[^PROCESSES.[$dataProcessID].main[$blockParam;$blockBody]]
}{
$result[]
}
#end @executeBlock[]
#################################################################################################
@printBlock[blockFields][data]
^if(^blockFields.is_not_empty.int(0)){
# сбор параметров блока
$blockParams[^parseBlockParams[$blockFields.attr]]
# сбор тела
$blockData[^taint[as-is][$blockFields.data]]
# передача управления обработчику блока (если есть)
^if(^blockFields.data_process_id.int(0)){
$blockData[^executeBlock[$blockFields.data_process_id;$blockParams;$blockData]]
}
# замена спец конструкций в теле блока
$blockData[^parseBlockPostProcess[$blockParams;$blockData]]
# вывод блока
$result[<$blockFields.name>$blockData</$blockFields.name>]
}{
# пустой блок без обработчика
$result[]
}
#end @printBlock[]
#################################################################################################
# из переданного xml формирует hash с параметрами обработки блока
@parseBlockParams[blockAttr]
# хэш блока
$result[^hash::create[]]
^if(def $blockAttr){
^try{
# xdoc документ с атрибутами блока
$params[^xdoc::create{<?xml version="1.0" encoding="$request:charset"?>
<params>
^taint[as-is][$blockAttr]
</params>
}]
# выборка список параметров
$params[^params.select[/params/*]]
# сбор хэша блока
^for[i](0;$params-1){
$node[$params.$i]
$result.[$node.nodeName][$node.firstChild.nodeValue]
}
}{
# если произошла ошибка сборки (обработки) xml
# как result - пустой хэш
^if($exception.type eq xml){$exception.handled(1)}
}
}
#end @parseBlockParams[]
#################################################################################################
# парсер блоков
# подразумевается вызов из обработчиков объектов
# для обработки блока name контекстного объекта -> ^parseBlock[name]
# для обработки блока name объекта с ID 777 (в его контексте) -> ^parseBlock[name;777]
@parse_block[name;objectID][object;oldObjectID;allBlocks;nameBlocks]
# подмена контекстного объекта
^if(^objectID.int(0) && $objectID != $OBJECT.id){
# объект подмены
$object[$OBJECT_HASH.[$objectID]]
^if(def $object){
# сохрание id контекстного объекта для будущего сосстановления
$oldObjectID($OBJECT.id)
# подмена $OBJECT
$OBJECT[$object]
}
}
# загрузка блоков
^if(!$BLOCKS.[$OBJECT.id].isLoaded){
$allBlocks[^getSqlBlocks[$.where[object_id = $OBJECT.id AND block.is_published = 1]]]
# хэш блоков по полю name
$allBlocks[^allBlocks.hash[name][$.distinct[tables]]]
# добавление блоков к хэш для повторного обращения
$BLOCKS.[$OBJECT.id][$allBlocks]
# бит - блоки загружены
$BLOCKS.[$OBJECT.id].isLoaded(1)
}
# кусок хэша с блоками name
$nameBlocks[$BLOCKS.[$OBJECT.id].[$name]]
^if(def $nameBlocks){
# обработка найденых блоков
$result[^nameBlocks.menu{^printBlock[$nameBlocks.fields]}]
}{
# совсем ничего нет
$result[]
}
# возврат контекстного объекта
^if($oldObjectID){
# обратная подмена подмена $OBJECT
$OBJECT[$OBJECT_HASH.[$oldObjectID]]
}
#end @parse_block[]
#################################################################################################
# для обратой совместимости
@parseBlock[name;objectID]
$result[^parse_block[$name;$objectID]]
#end @parseBlock[]Поправил немного код теперь обработчику передаётся 2 параметра(blockParam и blockBody).При обработке блока ошибки про maximum parameters больше нет, но появилась другая ошибка:В работе Parser произошла ошибка:И так далее...
call canceled - endless recursion detected
Ошибку вызвал этот фрагмент:
if
Ошибка произошла при работе с файлом:
//classes/engine.p, строка номер 352
Вот что говорится в FAQ об этой ошибке:
Подобное сообщение появляется, если парсеру кажется, что код зациклился. Очень часто причиной может быть некорректная или очень глубокая рекурсия (более 1000 вызовов).
Последовательность операций, которая привела к ошибке:
(от самой последней вверху списка до самой первой внизу)
* prepareProcesess: //classes/engine.p строка 407
* executeBlock: //classes/engine.p строка 442
* if: //classes/engine.p строка 441
* if: //classes/engine.p строка 433
* printBlock: //classes/engine.p строка 627
* menu: //classes/engine.p строка 627
* if: //classes/engine.p строка 625
* parse_block: //classes/engine.p строка 645
* parseBlock: //classes/shared/processes/process строка 14
* main: //classes/engine.p строка 410
* if: //classes/engine.p строка 409
* executeBlock: //classes/engine.p строка 442
* if: //classes/engine.p строка 441
* if: //classes/engine.p строка 433
* printBlock: //classes/engine.p строка 627
* menu: //classes/engine.p строка 627
* if: //classes/engine.p строка 625
* parse_block: //classes/engine.p строка 645
* parseBlock: //classes/shared/processes/process строка 14
* main: //classes/engine.p строка 410
* if: //classes/engine.p строка 409
* executeBlock: //classes/engine.p строка 442
* if: //classes/engine.p строка 441
* if: //classes/engine.p строка 433
* printBlock: //classes/engine.p строка 627
* menu: //classes/engine.p строка 627
* if: //classes/engine.p строка 625
* parse_block: //classes/engine.p строка 645
* parseBlock: //classes/shared/processes/process строка 14
* main: //classes/engine.p строка 410
* if: //classes/engine.p строка 409
* executeBlock: //classes/engine.p строка 442
* if: //classes/engine.p строка 441
* if: //classes/engine.p строка 433
* printBlock: //classes/engine.p строка 627
* menu: //classes/engine.p строка 627
* if: //classes/engine.p строка 625
* parse_block: //classes/engine.p строка 645
* parseBlock: //classes/shared/processes/process строка 14
* main: //classes/engine.p строка 410
* if: //classes/engine.p строка 409
* executeBlock: //classes/engine.p строка 442
* if: //classes/engine.p строка 441
* if: //classes/engine.p строка 433
* printBlock: //classes/engine.p строка 627
..................................................