render.class.php 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. <?php
  2. /**
  3. * The dom widget class file of zin of ZenTaoPMS.
  4. *
  5. * @copyright Copyright 2023 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
  6. * @author Hao Sun <sunhao@easycorp.ltd>
  7. * @package zin
  8. * @version $Id
  9. * @link https://www.zentao.net
  10. */
  11. namespace zin;
  12. require_once dirname(__DIR__) . DS . 'utils' . DS . 'deep.func.php';
  13. require_once __DIR__ . DS . 'selector.func.php';
  14. require_once __DIR__ . DS . 'node.class.php';
  15. require_once __DIR__ . DS . 'context.func.php';
  16. class render
  17. {
  18. /**
  19. * @var \zin\node
  20. */
  21. public $node;
  22. /**
  23. * @var bool
  24. */
  25. public $renderInner;
  26. /**
  27. * @var string
  28. */
  29. public $renderType;
  30. /**
  31. * @var mixed[]
  32. */
  33. public $selectors = array();
  34. /**
  35. * @var mixed[]
  36. */
  37. public $filteredMap = array();
  38. /**
  39. * Construct the dom object.
  40. *
  41. * @param node $node
  42. * @param array $children
  43. * @param array|string|object $selectors
  44. * @access public
  45. * @param string $renderType
  46. * @param bool $renderInner
  47. */
  48. public function __construct($node, $selectors = null, $renderType = 'html', $renderInner = false)
  49. {
  50. $this->node = $node;
  51. $this->renderType = $renderType;
  52. $this->renderInner = $renderInner;
  53. $this->addSelectors($selectors);
  54. }
  55. /**
  56. * @param \zin\stdClass $data
  57. * @param \zin\node $node
  58. */
  59. public function handleBuildNode($data, $node)
  60. {
  61. if(!$this->selectors || (isset($data->removed) && $data->removed)) return;
  62. foreach($this->selectors as $name => $selector)
  63. {
  64. if(isset($selector->command)) continue;
  65. if(!isset($this->filteredMap[$name])) $this->filteredMap[$name] = array();
  66. $filteredNodes = $this->filteredMap[$name];
  67. if(!$node->isMatch($selector)) continue;
  68. if($node instanceof h && $node->parent)
  69. {
  70. if($node->parent instanceof wg && $node->parent->isMatch($selector)) continue;
  71. if($node->parent->parent && $node->parent->parent instanceof wg && $node->parent->parent->isMatch($selector)) continue;
  72. }
  73. if($selector->id || $selector->first) $filteredNodes = array();
  74. $filteredNodes[$node->gid] = $node;
  75. $this->filteredMap[$name] = $filteredNodes;
  76. }
  77. }
  78. /**
  79. * @return string|mixed[]|object
  80. */
  81. public function render()
  82. {
  83. $this->node->prebuild();
  84. if($this->renderType === 'list') return $this->renderList();
  85. if($this->renderType === 'json') return $this->renderJson();
  86. return $this->renderHtml();
  87. }
  88. public function renderList()
  89. {
  90. global $app;
  91. $isUserLogon = isset($app->user) && $app->user->account != 'guest';
  92. $list = array();
  93. foreach($this->selectors as $selector)
  94. {
  95. $name = $selector->name;
  96. if(isset($selector->command))
  97. {
  98. $item = new stdClass();
  99. $item->name = $name;
  100. $item->type = 'data';
  101. $item->selector = $selector->selector;
  102. $item->data = (!$isUserLogon || $selector->disabled) ? null : data($selector->command);
  103. $list[] = $item;
  104. }
  105. else
  106. {
  107. $nodes = $this->filteredMap[$name];
  108. $item = new stdClass();
  109. $item->name = $name;
  110. $item->selector = stringifySelectors($selector);
  111. if(isset($selector->options['type']) && $selector->options['type'] === 'json')
  112. {
  113. $item->type = 'json';
  114. $item->data = array();
  115. $dataGetters = isset($selector->options['data']) ? $selector->options['data'] : null;
  116. $dataPorps = $dataGetters ? explode('|', $dataGetters) : null;
  117. foreach($nodes as $node)
  118. {
  119. $json = $node->toJSON();
  120. if($dataPorps)
  121. {
  122. $data = array();
  123. foreach($dataPorps as $prop)
  124. {
  125. $prop = trim($prop);
  126. if(empty($prop)) continue;
  127. $parts = explode('~', $prop, 2);
  128. $name = $parts[0];
  129. $namePath = count($parts) > 1 ? $parts[1] : $parts[0];
  130. $data[$name] = \zin\utils\deepGet($json, $namePath);
  131. }
  132. $item->data[] = $data;
  133. }
  134. else
  135. {
  136. $item->data[] = $json;
  137. }
  138. }
  139. if(count($item->data) === 1) $item->data = $item->data[0];
  140. }
  141. else
  142. {
  143. $html = array();
  144. foreach($nodes as $node)
  145. {
  146. $html[] = $selector->inner ? $node->renderInner() : $node->render();
  147. }
  148. $item->type = 'html';
  149. $item->data = implode("\n", $html);
  150. }
  151. $list[] = $item;
  152. }
  153. }
  154. return $list;
  155. }
  156. /**
  157. * Render dom to json object.
  158. *
  159. * @access public
  160. * @return object
  161. */
  162. public function renderJson()
  163. {
  164. global $app;
  165. $isUserLogon = isset($app->user) && $app->user->account != 'guest';
  166. $output = new stdClass();
  167. $output->data = array();
  168. foreach($this->selectors as $selector)
  169. {
  170. $name = $selector->name;
  171. if(isset($selector->command))
  172. {
  173. $output->data[$name] = (!$isUserLogon || $selector->disabled) ? null : data($selector->command);
  174. }
  175. else
  176. {
  177. $nodes = $this->filteredMap[$name];
  178. $list = array();
  179. foreach($nodes as $node)
  180. {
  181. $list[] = $node->toJSON();
  182. }
  183. $output->$name = $list;
  184. }
  185. }
  186. return $output;
  187. }
  188. public function renderHtml()
  189. {
  190. if($this->filteredMap) return renderToHtml(array_values($this->filteredMap));
  191. return $this->node->render();
  192. }
  193. /**
  194. * @param null|object|string|mixed[] $selectors
  195. */
  196. public function addSelectors($selectors)
  197. {
  198. if(!$selectors) return;
  199. global $config;
  200. $selectors = parseSelectors($selectors);
  201. foreach($selectors as $selector)
  202. {
  203. $selector->disabled = !empty($selector->command) && !in_array($selector->command, $config->zin->allowCommands);
  204. $this->selectors[$selector->name] = $selector;
  205. }
  206. }
  207. }