/Release/Last/Framework/Lib/report/Mockup.php

https://github.com/sergiygladkyy/OEF · PHP · 283 lines · 163 code · 61 blank · 59 comment · 26 complexity · 0d5c306e1a1b42ec21bf430d9b713562 MD5 · raw file

  1. <?php
  2. require_once('lib/report/Grid.php');
  3. require_once('lib/report/Area.php');
  4. class Mockup extends Grid
  5. {
  6. public function __construct($filepath)
  7. {
  8. $this->parseMockup($filepath);
  9. //echo '<hr><pre>'.print_r($this->area, true).'</pre>';
  10. //echo '<hr><pre>'.print_r($this->grid, true).'</pre>';
  11. //echo '<hr><pre>'.print_r($this->size, true).'</pre>';
  12. }
  13. /**
  14. * Parse mockup
  15. *
  16. * @param string $filepath
  17. * @return void
  18. */
  19. protected function parseMockup($filepath)
  20. {
  21. $sxml = simplexml_load_file($filepath);
  22. $xml = $sxml->body->table[0];
  23. $index = 0;
  24. $current_col = 0;
  25. foreach ($xml->xpath('colgroup') as $colgroup)
  26. {
  27. $index++;
  28. foreach ($colgroup->children() as $col)
  29. {
  30. $current_col++;
  31. if (!empty($col['area']))
  32. {
  33. $end = $current_col + (isset($col['span']) ? $col['span']: 1) - 1;
  34. $this->addArea($col['area'], array($current_col, 0, $end, 0));
  35. }
  36. }
  37. }
  38. $this->size['C'] = $current_col;
  39. $index = 0;
  40. $current_row = 0;
  41. foreach ($xml->xpath('tr') as $tr)
  42. {
  43. /* Row params */
  44. $current_row++;
  45. if (!empty($tr['area']))
  46. {
  47. $this->addArea($tr['area'], array(0, $current_row, 0, $current_row));
  48. }
  49. $this->grid[$current_row][0] = array();
  50. $row =& $this->grid[$current_row][0];
  51. $row['attributes'] = $this->getAttributes($tr);
  52. // Decode
  53. if (isset($row['attributes']['decode']))
  54. {
  55. $row['decode'] = $this->getDecodes($row['attributes']['decode']);
  56. unset($row['attributes']['decode']);
  57. }
  58. /* Cell params */
  59. $current_col = 0;
  60. foreach ($tr->children() as $td)
  61. {
  62. $current_col++;
  63. // Skip the filled 'rowspan' cells
  64. while (isset($this->grid[$current_row][$current_col])) $current_col++;
  65. // Params
  66. $content = $this->getContent($td);
  67. $this->grid[$current_row][$current_col] = array();
  68. $cell =& $this->grid[$current_row][$current_col];
  69. $cell['tag'] = $td->getName();
  70. $cell['content'] = $content;
  71. $cell['parameters'] = $content ? $this->getParameters($content) : array();
  72. $cell['attributes'] = $this->getAttributes($td);
  73. // Decode
  74. if (isset($cell['attributes']['decode']))
  75. {
  76. $cell['decode'] = $this->getDecodes($cell['attributes']['decode']);
  77. unset($cell['attributes']['decode']);
  78. }
  79. // Current cells Span
  80. $width = empty($td['colspan']) ? 0 : $td['colspan'] - 1;
  81. $height = empty($td['rowspan']) ? 0 : $td['rowspan'] - 1;
  82. // Area
  83. if (!empty($td['area']))
  84. {
  85. $this->addArea($td['area'], array($current_col, $current_row, $current_col + $width, $current_row + $height));
  86. }
  87. // Fill Span cells
  88. if (!$height && !$width) continue;
  89. $end_col = $current_col + $width;
  90. $end_row = $current_row + $height;
  91. for ($r = $current_row + 1; $r <= $end_row; $r++)
  92. {
  93. for ($c = $current_col; $c <= $end_col; $c++)
  94. {
  95. $this->grid[$r][$c]['in'] = array($current_col, $current_row, $end_col, $end_row);
  96. }
  97. }
  98. if (!$width) continue;
  99. for ($c = $current_col + 1; $c <= $end_col; $c++)
  100. {
  101. $this->grid[$current_row][$c]['in'] = array($current_col, $current_row, $end_col, $end_row);
  102. }
  103. $current_col = $end_col;
  104. }
  105. if ($current_col > $this->size['C']) $this->size['C'] = $current_col;
  106. }
  107. $this->size['R'] = $current_row;
  108. if (!empty($this->area)) $this->normalizeArea($this->area);
  109. }
  110. /**
  111. * Add area info
  112. *
  113. * @param string $names
  114. * @param array $coord
  115. * @return boolean
  116. */
  117. protected function addArea($names, array $coord)
  118. {
  119. if (!preg_match_all('/(?<=[\s]|\A)[A-Za-z_][A-Za-z_0-9]*(?=[\s]|\z)/i', $names, $matches))
  120. {
  121. return false;
  122. }
  123. foreach ($matches[0] as $name)
  124. {
  125. $this->area[$name]['coord'][] = $coord;
  126. }
  127. return true;
  128. }
  129. /**
  130. * Get element content
  131. *
  132. * @param SimpleXMLElement $el
  133. * @return string or null
  134. */
  135. protected function getContent(SimpleXMLElement $el)
  136. {
  137. $dom_sxe = dom_import_simplexml($el);
  138. if (!$dom_sxe) return null;
  139. $dom = new DOMDocument();
  140. $dom_sxe = $dom->importNode($dom_sxe, true);
  141. $dom_sxe = $dom->appendChild($dom_sxe);
  142. if (!$content = $dom->saveHTML()) return null;
  143. $start = strpos($content, '>') + 1;
  144. $length = strrpos($content, '<') - $start;
  145. return substr($content, $start, $length);
  146. }
  147. /**
  148. * Get contents variables
  149. *
  150. * @param string $content
  151. * @return array
  152. */
  153. protected function getParameters($content)
  154. {
  155. if (!preg_match_all('/(?<=\[)[A-Za-z_][A-Za-z_0-9]*?(?=\])/i', $content, $matches)) return array();
  156. return $matches[0];
  157. }
  158. /**
  159. * Get attributes list
  160. *
  161. * @param SimpleXMLElement $el
  162. * @return array
  163. */
  164. protected function getAttributes(SimpleXMLElement $el)
  165. {
  166. $res = array();
  167. foreach ($el->attributes() as $name => $value) $res[$name] = (string) $value;
  168. return $res;
  169. }
  170. /**
  171. * Return decodes array
  172. *
  173. * @param string $decodes - 'dec_1 dec_2 ..'
  174. * @return unknown_type
  175. */
  176. protected function getDecodes($decodes)
  177. {
  178. $decodes = trim($decodes);
  179. if (empty($decodes)) return array();
  180. if (!preg_match_all('/[\S]+/i', $decodes, $matches)) return array();
  181. $res = array();
  182. foreach ($matches[0] as $decode)
  183. {
  184. $res[$decode] = null;
  185. }
  186. return $res;
  187. }
  188. /**
  189. * Normalize Area
  190. *
  191. * @param array& $area
  192. * @return array
  193. */
  194. protected function normalizeArea(array& $area)
  195. {
  196. foreach ($area as $name => &$params)
  197. {
  198. if (!is_array($params['coord'][0])) continue;
  199. $coord = $params['coord'][0];
  200. $cnt = count($params['coord']);
  201. for ($i = 1; $i < $cnt; $i++)
  202. {
  203. $_coord =& $params['coord'][$i];
  204. if ($coord[0] > $_coord[0]) $coord[0] = $_coord[0];
  205. if ($coord[1] > $_coord[1]) $coord[1] = $_coord[1];
  206. if ($coord[2] < $_coord[2]) $coord[2] = $_coord[2];
  207. if ($coord[3] < $_coord[3]) $coord[3] = $_coord[3];
  208. }
  209. $params['coord'] = $coord;
  210. }
  211. return $area;
  212. }
  213. /**
  214. * (non-PHPdoc)
  215. * @see lib/report/Grid#getArea($id)
  216. */
  217. public function getArea($id)
  218. {
  219. $grid = parent::getArea($id);
  220. return is_null($grid) ? null : new Area($grid);
  221. }
  222. }