Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <?php
- class FormParser
- {
- /**
- * @var BaseCtrl[]
- */
- var $tagStack = array();
- var $objParser;
- var $strXmlData;
- var $DataSet;
- var $isDataset;
- var $dataCtrls = array('DataSet', 'Action', 'Module');
- var $genTags = array(
- 'StatformParams', 'WebReport', 'UnitView', 'Composition',
- 'UnitEdit', 'UnitProps', 'UnitEditGenerate', 'Template', 'Container',
- 'ContainerShort', 'SubForm', 'ModuleImage', 'ReportParams', 'PreviewTemplate',
- 'UserProcParams', 'TemplateFillAuto', 'TemplateMassFillAuto', 'TemplateDirParams', 'ImportGrid',
- 'Popup', 'ProtectedBlock', 'StatGrid', 'StatColumn', 'Grid', 'Column', 'FilterItem','TemplateDirServ');
- private $frmtext = '';
- private $diffSet = false;
- /**
- * @param $strInputXML
- * @param string|null $DataSet
- * @param Base $Parent
- * @param bool $frmout
- * @param null $frmtextout
- */
- function parse($strInputXML, $DataSet = null, $Parent = null, $frmout = false, &$frmtextout = null)
- {
- $this->theme = get_option('Theme');
- $this->DataSet = $DataSet;
- if(isset($Parent))
- {
- if(is_design_mode())
- $Parent->sym = '';
- array_push($this->tagStack, $Parent);
- }
- // standard XML parse object setup
- $strInputXML = '<?xml version="1.0" encoding="UTF-8" ?>' . createComments($strInputXML);
- $this->objParser = xml_parser_create("");
- xml_set_object($this->objParser, $this);
- xml_parser_set_option($this->objParser, XML_OPTION_CASE_FOLDING, 0);
- xml_set_element_handler($this->objParser, "tagOpen", "tagClosed");
- xml_set_character_data_handler($this->objParser, "tagData");
- $this->strXmlData = xml_parse($this->objParser, $strInputXML);
- if($this->diffSet)
- $this->unsetFormDiff();
- /*if(count($this->tagStack) > 0)
- {
- die('XML parse error');
- }*/
- if(!$this->strXmlData)
- {
- die(sprintf("XML error: %s at line %d",
- xml_error_string(xml_get_error_code($this->objParser)),
- xml_get_current_line_number($this->objParser)));
- }
- $frmtextout = $this->frmtext;
- xml_parser_free($this->objParser);
- }
- function tagOpen($parser, $name, $attrs)
- {
- // push the current tag name to an array of still-open tag names
- if($name == 'dummy')
- return;
- $attrs = array_change_key_case($attrs, CASE_LOWER);
- if(isset($GLOBALS['_CURRENT_FORM']) && $GLOBALS['_CURRENT_FORM'] != '')
- {
- $attrs['formname'] = $GLOBALS['_CURRENT_FORM'];
- if($name != 'component')
- $attrs['cmptype'] = 'Form';
- $GLOBALS['_CURRENT_FORM'] = '';
- }
- $parent = null;
- if(count($this->tagStack))
- $parent = $this->tagStack[count($this->tagStack) - 1];
- if(is_design_mode())
- {
- if($parent && $parent->supresschild)
- $attrs['uid'] = $parent->attrs['uid'];
- else
- $attrs['uid'] = getUnqId();
- if($parent)
- {
- $this->frmtext .= $parent->sym;
- $parent->sym = '';
- }
- $this->frmtext .= "<$name" . GetAttrStringFromArray($attrs);
- $sym = ">";
- }
- $del = false;
- //DForm
- if(isset($attrs['name']) && (!$parent || !$parent->_delete))
- {
- $this->insertDiffNodes($attrs['name'], 'before');
- $del = $this->checkDiffNodes($attrs['name'], 'delete');
- if(!$del)
- $this->DiffAttrs($attrs['name'], $attrs);
- }
- if($del || ($parent && $parent->_delete))
- {
- $obj = new Base($attrs, $parent);
- $obj->_delete = true;
- }
- else
- if($name != "component")
- {
- if(!isset($this->DataSet))
- $obj = new HTMLTag($name, $attrs, $parent);
- else
- $obj = new NotPrintableTag($name, $attrs, $parent);
- }
- else
- {
- if(in_array($attrs['cmptype'], $this->dataCtrls) && $attrs['name'] == $this->DataSet)
- $this->isDataset = true;
- if(!isset($this->DataSet) || $this->isDataset || in_array($attrs['cmptype'], $this->genTags))
- {
- $tclass = $attrs['cmptype'].'_'.$this->theme;
- if(class_exists($tclass))
- $obj = new $tclass($attrs, $parent);
- else
- $obj = new $attrs['cmptype']($attrs, $parent);
- }else
- $obj = new NotPrintableTag($name, $attrs, $parent);
- }
- if(is_design_mode())
- $obj->sym = $sym;
- array_push($this->tagStack, $obj);
- if(!($del || $parent && $parent->_delete))
- $this->insertDiffNodes($obj->_name, 'begin');
- }
- function tagData($parser, $tagData)
- {
- $parent = null;
- if(count($this->tagStack))
- $parent = $this->tagStack[count($this->tagStack) - 1];
- // set the latest open tag equal to the tag data
- if($parent && !$parent->_delete && (!isset($this->DataSet) || $this->isDataset || in_array($parent->CmpType, $this->genTags)))
- $parent->SetInnerText($tagData);
- if(is_design_mode())
- {
- $this->frmtext .= $parent->sym . str_replace(array('&', '<', '>'), array('&', '<', '>'), $tagData);
- $parent->sym = '';
- }
- //print($tagData);
- }
- function tagClosed($parser, $name)
- {
- // pop this tag (and any subsequent tags) off the stack of open tag names
- if($name == 'dummy')
- return;
- for($i = count($this->tagStack) - 1; $i >= 0; $i--)
- {
- $currTag = $this->tagStack[$i];
- $currName = $currTag->tag;
- if(is_design_mode())
- $sym = $currTag->sym;
- if(!$currTag->_delete)
- {
- if(!isset($this->DataSet) || in_array($currTag->CmpType, $this->genTags))
- {
- $this->insertDiffNodes($currTag->_name, 'end');
- if(count($this->tagStack) == 1)
- $currTag->SetSysInfo(form_geturlhelp());
- $currTag->Show();
- }
- else
- {
- if($currName == 'component' &&
- in_array($currTag->CmpType, $this->dataCtrls) /*$currTag->CmpType == 'DataSet'*/ &&
- $currTag->attrs['name'] == $this->DataSet)
- {
- $this->insertDiffNodes($currTag->_name, 'end');
- $currTag->ShowXML();
- $this->isDataset = false;
- //xml_parser_free($parser);
- //if($currTag->CmpType == 'DataSet') return false;
- }
- else
- {
- $this->insertDiffNodes($currTag->_name, 'end');
- $currTag->Show();
- }
- }
- }
- if(is_debug(5) && $currName == 'component' && (microtime(true) - $currTag->gentime) > 0.01)
- DebugInfoAdd('{' . (microtime(true) - $currTag->gentime) . "} time render component <$currTag->CmpType>");
- array_pop($this->tagStack);
- if(!$currTag->parent || !$currTag->parent->_delete)
- $this->insertDiffNodes($currTag->_name, 'after');
- if(is_design_mode())
- {
- //$this->frmtext .= $currTag->sym.'</'.$currName.'>';
- $this->frmtext .= $sym . '</' . $currName . '>';
- $sym = '';
- }
- if($currName == null || $currName == $name)
- {
- break;
- }
- }
- }
- function getInnerHTML($Node)
- {
- $chN = $Node->childNodes;
- $tmp = new DOMDocument();
- $uid = uniqid();
- $r = $tmp->createElement('root' . $uid);
- $tmp->appendChild($r);
- foreach($chN as $ch)
- {
- $r->appendChild($tmp->importNode($ch, true));
- }
- return str_replace(array('<root' . $uid . '>', '</root' . $uid . '>'), '', $tmp->saveXML($r));
- }
- function setFormDiff($formName)
- {
- if(!class_exists('DOMDocument'))
- {
- trigger_error('Diff Form is not used. DOM module is not installed.', E_USER_WARNING);
- return;
- }
- $infoDiff = array();
- $diffFiles = array();
- $path = getFormDiffPath($formName, $diffFiles);
- $infoDiff['__DIR__'] = ($path) ? $formName . '.d/' : '';
- $d = count($GLOBALS['_FORM_DIFF_']);
- $fullpath = '';
- $disMdl = get_option('enabled_modules');
- do
- {
- if(count($diffFiles) > 0)
- {
- $diff = '';
- foreach($diffFiles as $file)
- {
- $diff .= file_get_contents($file);
- }
- if($diff != '')
- {
- $xml = new DOMDocument();
- $xml->loadXML('<?xml version="1.0" encoding="UTF-8" ?><diff>' . $diff . '</diff>', LIBXML_NOBLANKS);
- $modules = $xml->getElementsByTagName('module');
- $ml = $modules->length;
- if($ml > 0)
- {
- $i = 0;
- $nTD = array();
- /**
- * @var DomElement $mdl
- */
- while($mdl = $modules->item($i++))
- {
- $mN = $mdl->getAttribute('name');
- if(!in_array($mN, $disMdl))
- {
- $nTD[] = $mdl;
- }
- }
- foreach($nTD as $n)
- {
- $n->parentNode->removeChild($n);
- }
- }
- $attrs = $xml->getElementsByTagName('attr');
- $nodes = $xml->getElementsByTagName('node');
- if(!$attrs->length && !$nodes->length && !$ml)
- {
- die('Error parse diff. Check syntax. Not found Node and Attr tags.');
- }
- $i = 0;
- /**
- * @var DomElement $attr
- * @var DomElement $node
- */
- while($attr = $attrs->item($i++))
- {
- $trg = $attr->getAttribute('target');
- $name = $attr->getAttribute('name');
- $data = array(
- $name => $attr->getAttribute('value')
- );
- $pos = $attr->getAttribute('pos');
- if($trg == '' || $pos == '' || $name == '')
- continue;
- if(isset($infoDiff[$trg]['attrs'][$pos]))
- $infoDiff[$trg]['attrs'][$pos][$name] = ((isset($infoDiff[$trg]['attrs'][$pos][$name])) ? $infoDiff[$trg]['attrs'][$pos][$name] : '') . $data[$name];
- else
- $infoDiff[$trg]['attrs'][$pos] = $data;
- }
- $i = 0;
- while($node = $nodes->item($i++))
- {
- $trg = $node->getAttribute('target');
- $data = array(
- 'value' => $this->getInnerHTML($node)
- );
- $pos = $node->getAttribute('pos');
- if($trg == '' || $pos == '')
- continue;
- if($pos == 'replace')
- {
- $pos = 'before';
- $infoDiff[$trg]['nodes']['delete'] = true;
- }
- if(isset($infoDiff[$trg]['nodes'][$pos]))
- @$infoDiff[$trg]['nodes'][$pos]['value'] .= $data['value'];
- else
- $infoDiff[$trg]['nodes'][$pos] = $data;
- }
- }
- }
- $d--;
- if($d < 0 || $GLOBALS['_FORM_DIFF_'][$d]['__DIR__'] == '')
- break;
- $fullpath = $GLOBALS['_FORM_DIFF_'][$d]['__DIR__'] . $fullpath;
- $diffFiles = array();
- $path = getFormDiffPath($fullpath . $formName, $diffFiles);
- $infoDiff['__DIR__'] = ($path) ? $formName . '.d/' : '';
- } while(true);
- array_push($GLOBALS['_FORM_DIFF_'], $infoDiff);
- $this->diffSet = true;
- }
- function unsetFormDiff()
- {
- array_pop($GLOBALS['_FORM_DIFF_']);
- }
- function getFormDiffInfo()
- {
- $d = count($GLOBALS['_FORM_DIFF_']);
- if($d > 0)
- return $GLOBALS['_FORM_DIFF_'][$d - 1];
- else
- return array();
- }
- function DiffAttrs($target, &$attrs)
- {
- if(empty($target))
- return;
- $dinf = $this->getFormDiffInfo();
- if(isset($dinf[$target]['attrs']))
- {
- foreach($dinf[$target]['attrs'] as $pos => $dataArray)
- {
- //call_user_func(array($this,$pos.'DiffAttrs'),&$attrs,$dataArray);
- switch($pos)
- {
- case 'before':
- $this->beforeDiffAttrs($attrs, $dataArray);
- break;
- case 'after':
- $this->afterDiffAttrs($attrs, $dataArray);
- break;
- case 'replace':
- $this->replaceDiffAttrs($attrs, $dataArray);
- break;
- case 'delete':
- $this->deleteDiffAttrs($attrs, $dataArray);
- break;
- case 'add':
- $this->addDiffAttrs($attrs, $dataArray);
- break;
- }
- }
- }
- }
- function beforeDiffAttrs(&$attrs, $dataArray)
- {
- foreach($dataArray as $name => $value)
- {
- $attrs[$name] = $value . $attrs[$name];
- }
- }
- function afterDiffAttrs(&$attrs, $dataArray)
- {
- foreach($dataArray as $name => $value)
- {
- $attrs[$name] .= $value;
- }
- }
- function replaceDiffAttrs(&$attrs, $dataArray)
- {
- foreach($dataArray as $name => $value)
- {
- $attrs[$name] = $value;
- }
- }
- function deleteDiffAttrs(&$attrs, $dataArray)
- {
- foreach($dataArray as $name => $value)
- {
- unset($attrs[$name]);
- }
- }
- function addDiffAttrs(&$attrs, $dataArray)
- {
- $this->replaceDiffAttrs($attrs, $dataArray);
- }
- function insertDiffNodes($target, $pos)
- {
- if(empty($target))
- return;
- $dinf = $this->getFormDiffInfo();
- if(!isset($dinf[$target]['nodes'][$pos]))
- return;
- $parent = null;
- if(count($this->tagStack))
- $parent = $this->tagStack[count($this->tagStack) - 1];
- $prs = new FormParser();
- $prs->setFormDiff('');
- $prs->isDataset = $this->isDataset;
- $prs->parse('<dummy>' . $dinf[$target]['nodes'][$pos]['value'] . '</dummy>', $this->DataSet, $parent);
- }
- function checkDiffNodes($target, $pos)
- {
- if(empty($target))
- return false;
- $dinf = $this->getFormDiffInfo();
- return isset($dinf[$target]['nodes'][$pos]);
- }
- }
- //Стек для форм
- $GLOBALS['_FORM_DIFF_'] = array();
- function getFormDiffPath($FormName, &$files)
- {
- $FormName = str_replace('\\','/',$FormName);
- $a = explode('.d/', $FormName);
- $c = count($a);
- while($c > 1)
- {
- $c--;
- $l = explode('/', $a[$c]);
- $f = explode('/', $a[$c - 1]);
- $bool = true;
- $res = array();
- for($li = 0, $cl = count($l); $li < $cl; $li++)
- {
- if(!isset($f[$li]) || $f[$li] != $l[$li] || !$bool)
- {
- $res[] = $l[$li];
- $bool = false;
- }
- }
- $a[$c] = implode('/', $res);
- }
- $FormName = implode('.d/', $a);
- $path = '';
- if(is_dir($d = dirname($_SERVER["SCRIPT_FILENAME"]) . get_option('Forms') . $FormName . '.d/'))
- {
- $path = $d;
- if($dirh = @opendir($path))
- {
- while(($file = readdir($dirh)) !== false)
- {
- $pi = pathinfo($path . $file);
- if(is_dir($path . $file . '/') || $pi['extension'] != 'dfrm')
- continue;
- //Для замены если есть в UserForms
- $files[$file] = $path . $file;
- }
- closedir($dirh);
- }
- }
- if(is_dir($d = dirname($_SERVER["SCRIPT_FILENAME"]) . getUserForms() . $FormName . '.d/'))
- {
- $path = $d;
- if($dirh = @opendir($path))
- {
- while(($file = readdir($dirh)) !== false)
- {
- $pi = pathinfo($path . $file);
- if(is_dir($path . $file . '/') || $pi['extension'] != 'dfrm')
- continue;
- //Заменяем если есть в базовом
- $files[$file] = $path . $file;
- }
- closedir($dirh);
- }
- }
- return $path;
- }
- function GetAttrStringFromArray($arr)
- {
- $attr_str = null;
- foreach($arr as $key => $value)
- {
- $attr_str .= ' ' . $key . '="' . $value . '"';
- }
- return $attr_str;
- //$this->BildAttrString($this->attrs);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement