Advertisement
Guest User

Untitled

a guest
Jan 24th, 2020
128
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.27 KB | None | 0 0
  1. <?php
  2.  
  3. class FormParser
  4. {
  5.  
  6. /**
  7. * @var BaseCtrl[]
  8. */
  9. var $tagStack = array();
  10. var $objParser;
  11. var $strXmlData;
  12. var $DataSet;
  13. var $isDataset;
  14. var $dataCtrls = array('DataSet', 'Action', 'Module');
  15. var $genTags = array(
  16. 'StatformParams', 'WebReport', 'UnitView', 'Composition',
  17. 'UnitEdit', 'UnitProps', 'UnitEditGenerate', 'Template', 'Container',
  18. 'ContainerShort', 'SubForm', 'ModuleImage', 'ReportParams', 'PreviewTemplate',
  19. 'UserProcParams', 'TemplateFillAuto', 'TemplateMassFillAuto', 'TemplateDirParams', 'ImportGrid',
  20. 'Popup', 'ProtectedBlock', 'StatGrid', 'StatColumn', 'Grid', 'Column', 'FilterItem','TemplateDirServ');
  21. private $frmtext = '';
  22. private $diffSet = false;
  23.  
  24. /**
  25. * @param $strInputXML
  26. * @param string|null $DataSet
  27. * @param Base $Parent
  28. * @param bool $frmout
  29. * @param null $frmtextout
  30. */
  31. function parse($strInputXML, $DataSet = null, $Parent = null, $frmout = false, &$frmtextout = null)
  32. {
  33. $this->theme = get_option('Theme');
  34. $this->DataSet = $DataSet;
  35. if(isset($Parent))
  36. {
  37. if(is_design_mode())
  38. $Parent->sym = '';
  39. array_push($this->tagStack, $Parent);
  40. }
  41. // standard XML parse object setup
  42. $strInputXML = '<?xml version="1.0" encoding="UTF-8" ?>' . createComments($strInputXML);
  43. $this->objParser = xml_parser_create("");
  44. xml_set_object($this->objParser, $this);
  45. xml_parser_set_option($this->objParser, XML_OPTION_CASE_FOLDING, 0);
  46. xml_set_element_handler($this->objParser, "tagOpen", "tagClosed");
  47.  
  48. xml_set_character_data_handler($this->objParser, "tagData");
  49.  
  50. $this->strXmlData = xml_parse($this->objParser, $strInputXML);
  51.  
  52. if($this->diffSet)
  53. $this->unsetFormDiff();
  54.  
  55. /*if(count($this->tagStack) > 0)
  56. {
  57. die('XML parse error');
  58. }*/
  59.  
  60. if(!$this->strXmlData)
  61. {
  62. die(sprintf("XML error: %s at line %d",
  63. xml_error_string(xml_get_error_code($this->objParser)),
  64. xml_get_current_line_number($this->objParser)));
  65. }
  66. $frmtextout = $this->frmtext;
  67. xml_parser_free($this->objParser);
  68. }
  69.  
  70. function tagOpen($parser, $name, $attrs)
  71. {
  72. // push the current tag name to an array of still-open tag names
  73. if($name == 'dummy')
  74. return;
  75. $attrs = array_change_key_case($attrs, CASE_LOWER);
  76. if(isset($GLOBALS['_CURRENT_FORM']) && $GLOBALS['_CURRENT_FORM'] != '')
  77. {
  78. $attrs['formname'] = $GLOBALS['_CURRENT_FORM'];
  79. if($name != 'component')
  80. $attrs['cmptype'] = 'Form';
  81. $GLOBALS['_CURRENT_FORM'] = '';
  82. }
  83. $parent = null;
  84. if(count($this->tagStack))
  85. $parent = $this->tagStack[count($this->tagStack) - 1];
  86.  
  87. if(is_design_mode())
  88. {
  89. if($parent && $parent->supresschild)
  90. $attrs['uid'] = $parent->attrs['uid'];
  91. else
  92. $attrs['uid'] = getUnqId();
  93. if($parent)
  94. {
  95. $this->frmtext .= $parent->sym;
  96. $parent->sym = '';
  97. }
  98. $this->frmtext .= "<$name" . GetAttrStringFromArray($attrs);
  99. $sym = ">";
  100. }
  101.  
  102. $del = false;
  103. //DForm
  104. if(isset($attrs['name']) && (!$parent || !$parent->_delete))
  105. {
  106. $this->insertDiffNodes($attrs['name'], 'before');
  107. $del = $this->checkDiffNodes($attrs['name'], 'delete');
  108. if(!$del)
  109. $this->DiffAttrs($attrs['name'], $attrs);
  110. }
  111. if($del || ($parent && $parent->_delete))
  112. {
  113. $obj = new Base($attrs, $parent);
  114. $obj->_delete = true;
  115. }
  116. else
  117. if($name != "component")
  118. {
  119. if(!isset($this->DataSet))
  120. $obj = new HTMLTag($name, $attrs, $parent);
  121. else
  122. $obj = new NotPrintableTag($name, $attrs, $parent);
  123.  
  124. }
  125. else
  126. {
  127. if(in_array($attrs['cmptype'], $this->dataCtrls) && $attrs['name'] == $this->DataSet)
  128. $this->isDataset = true;
  129. if(!isset($this->DataSet) || $this->isDataset || in_array($attrs['cmptype'], $this->genTags))
  130. {
  131. $tclass = $attrs['cmptype'].'_'.$this->theme;
  132. if(class_exists($tclass))
  133. $obj = new $tclass($attrs, $parent);
  134. else
  135. $obj = new $attrs['cmptype']($attrs, $parent);
  136. }else
  137. $obj = new NotPrintableTag($name, $attrs, $parent);
  138. }
  139. if(is_design_mode())
  140. $obj->sym = $sym;
  141. array_push($this->tagStack, $obj);
  142. if(!($del || $parent && $parent->_delete))
  143. $this->insertDiffNodes($obj->_name, 'begin');
  144. }
  145.  
  146. function tagData($parser, $tagData)
  147. {
  148. $parent = null;
  149. if(count($this->tagStack))
  150. $parent = $this->tagStack[count($this->tagStack) - 1];
  151. // set the latest open tag equal to the tag data
  152. if($parent && !$parent->_delete && (!isset($this->DataSet) || $this->isDataset || in_array($parent->CmpType, $this->genTags)))
  153. $parent->SetInnerText($tagData);
  154. if(is_design_mode())
  155. {
  156. $this->frmtext .= $parent->sym . str_replace(array('&', '<', '>'), array('&amp;', '&lt;', '&gt;'), $tagData);
  157. $parent->sym = '';
  158. }
  159. //print($tagData);
  160. }
  161.  
  162.  
  163. function tagClosed($parser, $name)
  164. {
  165.  
  166. // pop this tag (and any subsequent tags) off the stack of open tag names
  167.  
  168. if($name == 'dummy')
  169. return;
  170.  
  171. for($i = count($this->tagStack) - 1; $i >= 0; $i--)
  172. {
  173. $currTag = $this->tagStack[$i];
  174. $currName = $currTag->tag;
  175. if(is_design_mode())
  176. $sym = $currTag->sym;
  177. if(!$currTag->_delete)
  178. {
  179.  
  180. if(!isset($this->DataSet) || in_array($currTag->CmpType, $this->genTags))
  181. {
  182. $this->insertDiffNodes($currTag->_name, 'end');
  183. if(count($this->tagStack) == 1)
  184. $currTag->SetSysInfo(form_geturlhelp());
  185. $currTag->Show();
  186. }
  187. else
  188. {
  189. if($currName == 'component' &&
  190. in_array($currTag->CmpType, $this->dataCtrls) /*$currTag->CmpType == 'DataSet'*/ &&
  191. $currTag->attrs['name'] == $this->DataSet)
  192. {
  193. $this->insertDiffNodes($currTag->_name, 'end');
  194. $currTag->ShowXML();
  195. $this->isDataset = false;
  196. //xml_parser_free($parser);
  197. //if($currTag->CmpType == 'DataSet') return false;
  198. }
  199. else
  200. {
  201. $this->insertDiffNodes($currTag->_name, 'end');
  202. $currTag->Show();
  203. }
  204. }
  205. }
  206. if(is_debug(5) && $currName == 'component' && (microtime(true) - $currTag->gentime) > 0.01)
  207. DebugInfoAdd('{' . (microtime(true) - $currTag->gentime) . "} time render component <$currTag->CmpType>");
  208. array_pop($this->tagStack);
  209. if(!$currTag->parent || !$currTag->parent->_delete)
  210. $this->insertDiffNodes($currTag->_name, 'after');
  211.  
  212. if(is_design_mode())
  213. {
  214. //$this->frmtext .= $currTag->sym.'</'.$currName.'>';
  215. $this->frmtext .= $sym . '</' . $currName . '>';
  216. $sym = '';
  217. }
  218. if($currName == null || $currName == $name)
  219. {
  220. break;
  221. }
  222. }
  223. }
  224.  
  225. function getInnerHTML($Node)
  226. {
  227. $chN = $Node->childNodes;
  228. $tmp = new DOMDocument();
  229. $uid = uniqid();
  230. $r = $tmp->createElement('root' . $uid);
  231. $tmp->appendChild($r);
  232. foreach($chN as $ch)
  233. {
  234. $r->appendChild($tmp->importNode($ch, true));
  235. }
  236. return str_replace(array('<root' . $uid . '>', '</root' . $uid . '>'), '', $tmp->saveXML($r));
  237. }
  238.  
  239. function setFormDiff($formName)
  240. {
  241. if(!class_exists('DOMDocument'))
  242. {
  243. trigger_error('Diff Form is not used. DOM module is not installed.', E_USER_WARNING);
  244. return;
  245. }
  246. $infoDiff = array();
  247. $diffFiles = array();
  248. $path = getFormDiffPath($formName, $diffFiles);
  249. $infoDiff['__DIR__'] = ($path) ? $formName . '.d/' : '';
  250. $d = count($GLOBALS['_FORM_DIFF_']);
  251. $fullpath = '';
  252. $disMdl = get_option('enabled_modules');
  253. do
  254. {
  255. if(count($diffFiles) > 0)
  256. {
  257. $diff = '';
  258. foreach($diffFiles as $file)
  259. {
  260. $diff .= file_get_contents($file);
  261. }
  262. if($diff != '')
  263. {
  264. $xml = new DOMDocument();
  265. $xml->loadXML('<?xml version="1.0" encoding="UTF-8" ?><diff>' . $diff . '</diff>', LIBXML_NOBLANKS);
  266. $modules = $xml->getElementsByTagName('module');
  267. $ml = $modules->length;
  268. if($ml > 0)
  269. {
  270. $i = 0;
  271. $nTD = array();
  272. /**
  273. * @var DomElement $mdl
  274. */
  275. while($mdl = $modules->item($i++))
  276. {
  277. $mN = $mdl->getAttribute('name');
  278. if(!in_array($mN, $disMdl))
  279. {
  280. $nTD[] = $mdl;
  281. }
  282. }
  283. foreach($nTD as $n)
  284. {
  285. $n->parentNode->removeChild($n);
  286. }
  287. }
  288.  
  289. $attrs = $xml->getElementsByTagName('attr');
  290. $nodes = $xml->getElementsByTagName('node');
  291. if(!$attrs->length && !$nodes->length && !$ml)
  292. {
  293. die('Error parse diff. Check syntax. Not found Node and Attr tags.');
  294. }
  295. $i = 0;
  296. /**
  297. * @var DomElement $attr
  298. * @var DomElement $node
  299. */
  300. while($attr = $attrs->item($i++))
  301. {
  302.  
  303. $trg = $attr->getAttribute('target');
  304. $name = $attr->getAttribute('name');
  305. $data = array(
  306. $name => $attr->getAttribute('value')
  307. );
  308. $pos = $attr->getAttribute('pos');
  309. if($trg == '' || $pos == '' || $name == '')
  310. continue;
  311. if(isset($infoDiff[$trg]['attrs'][$pos]))
  312. $infoDiff[$trg]['attrs'][$pos][$name] = ((isset($infoDiff[$trg]['attrs'][$pos][$name])) ? $infoDiff[$trg]['attrs'][$pos][$name] : '') . $data[$name];
  313. else
  314. $infoDiff[$trg]['attrs'][$pos] = $data;
  315. }
  316. $i = 0;
  317. while($node = $nodes->item($i++))
  318. {
  319. $trg = $node->getAttribute('target');
  320. $data = array(
  321. 'value' => $this->getInnerHTML($node)
  322. );
  323. $pos = $node->getAttribute('pos');
  324. if($trg == '' || $pos == '')
  325. continue;
  326. if($pos == 'replace')
  327. {
  328. $pos = 'before';
  329. $infoDiff[$trg]['nodes']['delete'] = true;
  330. }
  331. if(isset($infoDiff[$trg]['nodes'][$pos]))
  332. @$infoDiff[$trg]['nodes'][$pos]['value'] .= $data['value'];
  333. else
  334. $infoDiff[$trg]['nodes'][$pos] = $data;
  335. }
  336. }
  337. }
  338. $d--;
  339. if($d < 0 || $GLOBALS['_FORM_DIFF_'][$d]['__DIR__'] == '')
  340. break;
  341. $fullpath = $GLOBALS['_FORM_DIFF_'][$d]['__DIR__'] . $fullpath;
  342. $diffFiles = array();
  343. $path = getFormDiffPath($fullpath . $formName, $diffFiles);
  344. $infoDiff['__DIR__'] = ($path) ? $formName . '.d/' : '';
  345. } while(true);
  346. array_push($GLOBALS['_FORM_DIFF_'], $infoDiff);
  347. $this->diffSet = true;
  348. }
  349.  
  350. function unsetFormDiff()
  351. {
  352. array_pop($GLOBALS['_FORM_DIFF_']);
  353. }
  354.  
  355. function getFormDiffInfo()
  356. {
  357. $d = count($GLOBALS['_FORM_DIFF_']);
  358. if($d > 0)
  359. return $GLOBALS['_FORM_DIFF_'][$d - 1];
  360. else
  361. return array();
  362. }
  363.  
  364. function DiffAttrs($target, &$attrs)
  365. {
  366. if(empty($target))
  367. return;
  368.  
  369. $dinf = $this->getFormDiffInfo();
  370.  
  371. if(isset($dinf[$target]['attrs']))
  372. {
  373. foreach($dinf[$target]['attrs'] as $pos => $dataArray)
  374. {
  375. //call_user_func(array($this,$pos.'DiffAttrs'),&$attrs,$dataArray);
  376. switch($pos)
  377. {
  378. case 'before':
  379. $this->beforeDiffAttrs($attrs, $dataArray);
  380. break;
  381. case 'after':
  382. $this->afterDiffAttrs($attrs, $dataArray);
  383. break;
  384. case 'replace':
  385. $this->replaceDiffAttrs($attrs, $dataArray);
  386. break;
  387. case 'delete':
  388. $this->deleteDiffAttrs($attrs, $dataArray);
  389. break;
  390. case 'add':
  391. $this->addDiffAttrs($attrs, $dataArray);
  392. break;
  393. }
  394. }
  395. }
  396. }
  397.  
  398. function beforeDiffAttrs(&$attrs, $dataArray)
  399. {
  400. foreach($dataArray as $name => $value)
  401. {
  402. $attrs[$name] = $value . $attrs[$name];
  403. }
  404. }
  405.  
  406. function afterDiffAttrs(&$attrs, $dataArray)
  407. {
  408. foreach($dataArray as $name => $value)
  409. {
  410. $attrs[$name] .= $value;
  411. }
  412. }
  413.  
  414. function replaceDiffAttrs(&$attrs, $dataArray)
  415. {
  416. foreach($dataArray as $name => $value)
  417. {
  418. $attrs[$name] = $value;
  419. }
  420. }
  421.  
  422. function deleteDiffAttrs(&$attrs, $dataArray)
  423. {
  424. foreach($dataArray as $name => $value)
  425. {
  426. unset($attrs[$name]);
  427. }
  428. }
  429.  
  430. function addDiffAttrs(&$attrs, $dataArray)
  431. {
  432. $this->replaceDiffAttrs($attrs, $dataArray);
  433. }
  434.  
  435. function insertDiffNodes($target, $pos)
  436. {
  437. if(empty($target))
  438. return;
  439.  
  440. $dinf = $this->getFormDiffInfo();
  441.  
  442. if(!isset($dinf[$target]['nodes'][$pos]))
  443. return;
  444.  
  445. $parent = null;
  446. if(count($this->tagStack))
  447. $parent = $this->tagStack[count($this->tagStack) - 1];
  448.  
  449. $prs = new FormParser();
  450. $prs->setFormDiff('');
  451. $prs->isDataset = $this->isDataset;
  452. $prs->parse('<dummy>' . $dinf[$target]['nodes'][$pos]['value'] . '</dummy>', $this->DataSet, $parent);
  453. }
  454.  
  455. function checkDiffNodes($target, $pos)
  456. {
  457. if(empty($target))
  458. return false;
  459.  
  460. $dinf = $this->getFormDiffInfo();
  461. return isset($dinf[$target]['nodes'][$pos]);
  462. }
  463. }
  464.  
  465. //Стек для форм
  466. $GLOBALS['_FORM_DIFF_'] = array();
  467.  
  468. function getFormDiffPath($FormName, &$files)
  469. {
  470. $FormName = str_replace('\\','/',$FormName);
  471. $a = explode('.d/', $FormName);
  472. $c = count($a);
  473. while($c > 1)
  474. {
  475. $c--;
  476. $l = explode('/', $a[$c]);
  477. $f = explode('/', $a[$c - 1]);
  478. $bool = true;
  479. $res = array();
  480. for($li = 0, $cl = count($l); $li < $cl; $li++)
  481. {
  482. if(!isset($f[$li]) || $f[$li] != $l[$li] || !$bool)
  483. {
  484. $res[] = $l[$li];
  485. $bool = false;
  486. }
  487. }
  488. $a[$c] = implode('/', $res);
  489. }
  490. $FormName = implode('.d/', $a);
  491. $path = '';
  492. if(is_dir($d = dirname($_SERVER["SCRIPT_FILENAME"]) . get_option('Forms') . $FormName . '.d/'))
  493. {
  494. $path = $d;
  495. if($dirh = @opendir($path))
  496. {
  497. while(($file = readdir($dirh)) !== false)
  498. {
  499. $pi = pathinfo($path . $file);
  500. if(is_dir($path . $file . '/') || $pi['extension'] != 'dfrm')
  501. continue;
  502. //Для замены если есть в UserForms
  503. $files[$file] = $path . $file;
  504. }
  505. closedir($dirh);
  506. }
  507. }
  508.  
  509. if(is_dir($d = dirname($_SERVER["SCRIPT_FILENAME"]) . getUserForms() . $FormName . '.d/'))
  510. {
  511. $path = $d;
  512. if($dirh = @opendir($path))
  513. {
  514. while(($file = readdir($dirh)) !== false)
  515. {
  516. $pi = pathinfo($path . $file);
  517. if(is_dir($path . $file . '/') || $pi['extension'] != 'dfrm')
  518. continue;
  519. //Заменяем если есть в базовом
  520. $files[$file] = $path . $file;
  521. }
  522. closedir($dirh);
  523. }
  524. }
  525. return $path;
  526. }
  527.  
  528. function GetAttrStringFromArray($arr)
  529. {
  530. $attr_str = null;
  531.  
  532. foreach($arr as $key => $value)
  533. {
  534. $attr_str .= ' ' . $key . '="' . $value . '"';
  535. }
  536. return $attr_str;
  537. //$this->BildAttrString($this->attrs);
  538. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement