TestObj.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401
  1. <?php
  2. Lib::loadClass('OBJ');
  3. Lib::loadClass('Response');
  4. Lib::loadClass('Router');
  5. class Route_Storage_TestObj extends RouteBase {
  6. public function defaultAction() {
  7. }
  8. public function objectListAction() {
  9. UI::gora();
  10. UI::menu();
  11. try {
  12. throw new Exception("TODO...");
  13. } catch (Exception $e) {
  14. UI::alert('danger', "Error #" . $e->getCode() . "|" . $e->getLine() . ": " . $e->getMessage());
  15. }
  16. UI::dol();
  17. }
  18. public function coreObjectListAction() {
  19. UI::gora();
  20. UI::menu();
  21. Router::getRoute('Storage')->navView();
  22. try {
  23. $coreObjlist = OBJ::getCoreObjectList();
  24. $objectList = array();
  25. foreach ($coreObjlist as $objName) {
  26. $objItem = array();
  27. $objItem['name'] = $objName;
  28. $objItem['struktura'] = UI::h('a', [ 'href' => $this->getLink('coreObjectStruct', [ 'object' => $objName ]) ], "struct");
  29. // $objItem['label'] = "";// TODO: read from json
  30. $objectList[] = $objItem;
  31. }
  32. usort($objectList, function($rowA, $rowB) {
  33. $a = $rowA['nazwa']; $b = $rowB['nazwa'];
  34. if ($a == $b) return 0;
  35. return ($a < $b) ? -1 : 1;
  36. });
  37. DBG::table("objectList", $objectList, __CLASS__, __FUNCTION__, __LINE__);
  38. } catch (Exception $e) {
  39. UI::alert('danger', "Error #" . $e->getCode() . "|" . $e->getLine() . ": " . $e->getMessage());
  40. }
  41. UI::dol();
  42. }
  43. public function checkObjectInstallAjaxAction() {
  44. $response = array();
  45. try {
  46. $objectName = V::get('object', '', $_REQUEST, 'word');
  47. if (empty($objectName)) throw new Exception("Missing Object name");
  48. $response['object'] = $objectName;
  49. $json = OBJ::getCoreObjectFromFile($objectName);
  50. OBJ::checkInstall($json);
  51. $response['type'] = 'success';
  52. $response['msg'] = "OK - object installed";
  53. } catch (Exception $e) {
  54. $response['type'] = 'error';
  55. $response['msg'] = $e->getMessage();
  56. $response['code'] = $e->getCode();
  57. $response['line'] = $e->getLine();
  58. }
  59. Response::sendJsonExit($response);
  60. }
  61. public function coreObjectConnectAction() {
  62. UI::gora();
  63. UI::menu();
  64. Router::getRoute('Storage')->navView();
  65. try {
  66. $objectName = V::get('object', '', $_REQUEST, 'word');
  67. if (empty($objectName)) throw new Exception("Missing Object name");
  68. $json = OBJ::getCoreObjectFromFile($objectName);
  69. $label = OBJ::getLabel($json);
  70. $parentList = OBJ::getParentList($json);
  71. $linksParentList = array(); foreach ($parentList as $parentName) {
  72. $parentLink = UI::h('a', [ 'href' => $this->getLink('coreObjectStruct', [ 'object' => str_replace('/', '-', $parentName) ]) ], $parentName);
  73. array_unshift($linksParentList, $parentLink);
  74. }
  75. $ajaxCheckInstall = Router::getRoute('Storage_TestObj')->getLink('checkObjectInstallAjax', [ 'object' => $objectName ]);
  76. $onClick = "return p5UI__ButtonAjax(this, 'p5UIBtnAjax:Storage:checkObjectInstallAjax', { href: '{$ajaxCheckInstall}' })";
  77. $btnCheckInstall = '<a onclick="'.$onClick.'" href="#" title="check install db tables"><i class="glyphicon glyphicon-cog"></i></a>';
  78. UI::startContainer();
  79. echo UI::h('h1', [], "Obiekt <code>{$label}</code> <small>{$btnCheckInstall}</small>");
  80. if (!empty($parentList)) {
  81. echo UI::h('ol', [ 'class' => "breadcrumb" ], array_merge([
  82. '<li>Dziedziczy z:</li>',
  83. ], array_map(function ($parentLink) {
  84. return "<li>{$parentLink}</li>";
  85. }, $linksParentList)));
  86. // <li class="active">Data</li>
  87. // echo '<p>' . implode(", ", $parentList) . '</p>';
  88. }
  89. $tableOne = array();
  90. $tableOne['caption'] = 'Klasy';
  91. $tableOne['rows'] = array();
  92. $parentList = OBJ::getParentList($json);
  93. $tableOne['rows'][] = array('__primary_key' => $objectName, 'name' => $objectName);
  94. $linksParentList = array();
  95. foreach ($parentList as $parentName) {
  96. // $parentLink = UI::h('a', [ 'href' => $this->getLink('coreObjectStruct', [ 'object' => str_replace('/', '-', $parentName) ]) ], $parentName);
  97. // array_unshift($linksParentList, $parentLink);
  98. $tableOne['rows'][] = array('__primary_key' => $parentName, 'name' => $parentName);
  99. }
  100. $tableTwo = array();
  101. $tableTwo['caption'] = 'Rekordy w tabeli głównej';
  102. $mainTable = OBJ::getMainTableName($json);
  103. $sqlFields = OBJ::getTableFields($json);
  104. $tableTwo['rows'] = $this->getTableRows($mainTable, $sqlFields);
  105. foreach ($tableTwo['rows'] as $idx => $row) {
  106. // $tableTwo['rows'][] = array('__primary_key' => $objectName, 'name' => $objectName);
  107. $tableTwo['rows'][$idx]['__primary_key'] = $row['ID'];
  108. }
  109. echo '<hr>';
  110. // TODO: filter connected rows
  111. // TODO: filter not connected rows
  112. // TODO: action connect rows - args(schema, rows_primary_key_list)
  113. // TODO: action un connect rows - args(schema, rows_primary_key_list)
  114. $this->showConnectSchemaToTableWidget(compact('tableOne', 'tableTwo'));
  115. UI::endContainer();
  116. echo UI::h('script', [], "
  117. jQuery(document).on('p5UIBtnAjax:Storage:checkObjectInstallAjax:click', function(e, n, payload) {
  118. console.log('event p5UIBtnAjax:Storage:checkObjectInstallAjax:click', n, payload);
  119. });
  120. jQuery(document).on('p5UIBtnAjax:Storage:checkObjectInstallAjax:ajaxLoaded', function(e, n, payload) {
  121. console.log('event p5UIBtnAjax:Storage:checkObjectInstallAjax:ajaxLoaded', n, payload);
  122. if ('success' == payload.type) {
  123. // jQuery(n).parents('td').text(payload.body.id);
  124. }
  125. jQuery.notify(payload.msg, payload.type);
  126. });
  127. ");
  128. DBG::_(true, true, "json", $json, __CLASS__, __FUNCTION__, __LINE__);
  129. } catch (Exception $e) {
  130. UI::alert('danger', "Error #" . $e->getCode() . "|" . $e->getLine() . ": " . $e->getMessage());
  131. }
  132. UI::dol();
  133. }
  134. public function coreObjectStructAction() {
  135. UI::gora();
  136. UI::menu();
  137. Router::getRoute('Storage')->navView();
  138. try {
  139. $objectName = V::get('object', '', $_REQUEST, 'word');
  140. if (empty($objectName)) throw new Exception("Missing Object name");
  141. $json = OBJ::getCoreObjectFromFile($objectName);
  142. $label = OBJ::getLabel($json);
  143. $parentList = OBJ::getParentList($json);
  144. $linksParentList = array(); foreach ($parentList as $parentName) {
  145. $parentLink = UI::h('a', [ 'href' => $this->getLink('coreObjectStruct', [ 'object' => str_replace('/', '-', $parentName) ]) ], $parentName);
  146. array_unshift($linksParentList, $parentLink);
  147. }
  148. $ajaxCheckInstall = $this->getLink('checkObjectInstallAjax', [ 'object' => $objectName ]);
  149. $onClick = "return p5UI__ButtonAjax(this, 'p5UIBtnAjax:Storage:checkObjectInstallAjax', { href: '{$ajaxCheckInstall}' })";
  150. $btnCheckInstall = '<a onclick="'.$onClick.'" href="#" title="check install db tables"><i class="glyphicon glyphicon-cog"></i></a>';
  151. UI::startContainer();
  152. UI::tag('h1', [], "Obiekt <code>{$label}</code> <small>{$btnCheckInstall}</small>");
  153. if (!empty($parentList)) {
  154. UI::startTag('ol', ['class'=>"breadcrumb"]);
  155. UI::tag('li', [], "Dziedziczy z:");
  156. foreach ($linksParentList as $parentLink) {
  157. UI::tag('li', [], $parentLink);
  158. }
  159. // <!-- <li class="active">Data</li> -->
  160. UI::endTag('ol');
  161. // <!-- <p> implode(", ", $parentList);</p> -->
  162. }
  163. // TODO: UI::table(['rows'=>array_map()]);
  164. $jsonFields = OBJ::getFields($json);
  165. UI::table([
  166. 'caption' => "Struktura:",
  167. 'rows' => array_map(function ($field, $fieldName) {
  168. return [
  169. 'nazwa' => $fieldName,
  170. 'typ' => $field['type'],
  171. 'label' => $field['label'],
  172. 'json' => json_encode($field),
  173. ];
  174. }, $jsonFields, array_keys($jsonFields))
  175. ]);
  176. echo UI::h('a', [ 'class' => "btn btn-primary", 'href' => $this->getLink('coreObjectConnect', [ 'object' => $objectName ]) ], "Przypisz rekordy do klasy");
  177. $mainTable = OBJ::getMainTableName($json);
  178. $sqlFields = OBJ::getTableFields($json);
  179. $this->showTableWidget($mainTable, $sqlFields);
  180. UI::endContainer();
  181. echo UI::h('script', [], "
  182. jQuery(document).on('p5UIBtnAjax:Storage:checkObjectInstallAjax:click', function(e, n, payload) {
  183. console.log('event p5UIBtnAjax:Storage:checkObjectInstallAjax:click', n, payload);
  184. });
  185. jQuery(document).on('p5UIBtnAjax:Storage:checkObjectInstallAjax:ajaxLoaded', function(e, n, payload) {
  186. console.log('event p5UIBtnAjax:Storage:checkObjectInstallAjax:ajaxLoaded', n, payload);
  187. if ('success' == payload.type) {
  188. // jQuery(n).parents('td').text(payload.body.id);
  189. }
  190. jQuery.notify(payload.msg, payload.type);
  191. });
  192. ");
  193. DBG::_(true, true, "json", $json, __CLASS__, __FUNCTION__, __LINE__);
  194. } catch (Exception $e) {
  195. UI::alert('danger', "Error #" . $e->getCode() . "|" . $e->getLine() . ": " . $e->getMessage());
  196. }
  197. UI::dol();
  198. }
  199. public function coreObjectParseAllAction() {
  200. UI::gora();
  201. UI::menu();
  202. Router::getRoute('Storage')->navView();
  203. try {
  204. OBJ::parseAll();
  205. } catch (Exception $e) {
  206. UI::alert('danger', "Error #" . $e->getCode() . "|" . $e->getLine() . ": " . $e->getMessage());
  207. }
  208. UI::dol();
  209. }
  210. public function showConnectSchemaToTableWidget($params) {
  211. if (empty($params['tableOne'])) throw new Exception("Missing tableOne in Connect widget");
  212. if (empty($params['tableTwo'])) throw new Exception("Missing tableTwo in Connect widget");
  213. $tableOne = $params['tableOne'];
  214. $tableTwo = $params['tableTwo'];
  215. // TODO: add p5BtnAjax to table filters button
  216. // TODO: add p5BtnAjax to conn button
  217. $jsEventNamespace = 'ConnectTableWidget' . time();
  218. $htmlIdWrap = "{$jsEventNamespace}-wrap";
  219. $stateLogId = "{$jsEventNamespace}-state-log";
  220. $stateSelectedTotalId = "{$jsEventNamespace}-state-selected";
  221. $stateClearSelectedBtnId = "{$jsEventNamespace}-state-clear-selected-btn";
  222. foreach ($tableOne['rows'] as $idx => $r) {
  223. $tableOne['rows'][$idx]['@onClick'] = "return p5UI__Clickable(this, '{$jsEventNamespace}:tableOne', { primary_key: '{$r['__primary_key']}' });";
  224. }
  225. foreach ($tableTwo['rows'] as $idx => $r) {
  226. $tableTwo['rows'][$idx]['@onClick'] = "return p5UI__Clickable(this, '{$jsEventNamespace}:tableTwo', { primary_key: '{$r['__primary_key']}' });";
  227. }
  228. $tableOne['hidden_cols'] = $tableTwo['hidden_cols'] = array('__primary_key', '@onClick', '__html_id');
  229. $tableTwo['__html_id'] = "{$jsEventNamespace}-table-two";
  230. ?>
  231. <div id="<?php echo $htmlIdWrap; ?>">
  232. <?php UI::table($tableOne); ?>
  233. <div class="btn-group">
  234. <button class="btn btn-default" title="Wybierz rekordy wg instancji"><i class="glyphicon glyphicon-question-sign"></i></button>
  235. <button class="btn btn-default conn-btn-filter-yes">Przypisani</button>
  236. <button class="btn btn-default conn-btn-filter-no active">Nieprzypisani</button>
  237. <button class="btn btn-default conn-btn-filter-clear" title="Wszystkie"><i class="glyphicon glyphicon-remove"></i></button>
  238. </div>
  239. <div class="btn-group">
  240. <span style="padding-left:30px;">Zaznaczono
  241. <span class="conn-selected-total">0</span>
  242. <button class="conn-btn-clear-selected btn btn-link"
  243. onClick="return p5UI__Clickable(this, '<?php echo $jsEventNamespace; ?>:clearSelection', {});"
  244. style="display:none"><i class="glyphicon glyphicon-remove" style="color:red"></i></button>
  245. </span>
  246. </div>
  247. <?php UI::jsAjaxTable($tableTwo); ?>
  248. <pre class="conn-log"></pre>
  249. </div>
  250. <script>
  251. (function(){
  252. var state = {
  253. selectedTableOne: null,
  254. selectedTableTwo: [],
  255. filterSelected: 'no'
  256. }
  257. var props = {
  258. jsEventNamespace: '<?php echo $jsEventNamespace; ?>',
  259. htmlIdWrap: '<?php echo $htmlIdWrap; ?>',
  260. tableTwoId: '#<?php echo $tableTwo['__html_id']; ?>',
  261. stateSelectedTotalId: '#<?php echo $stateSelectedTotalId; ?>',
  262. stateClearSelectedBtnId: '#<?php echo $stateClearSelectedBtnId; ?>',
  263. stateLogId: '#<?php echo $stateLogId; ?>'
  264. }
  265. var wrap = jQuery('#' + props.htmlIdWrap);
  266. var jqNodes = {
  267. wrap: wrap,
  268. filter_yes: wrap.find('.conn-btn-filter-yes'),
  269. filter_no: wrap.find('.conn-btn-filter-no'),
  270. filter_clear: wrap.find('.conn-btn-filter-clear'),
  271. total_selected: wrap.find('.conn-selected-total'),
  272. btn_clear_selected: wrap.find('.conn-btn-clear-selected'),
  273. state_log: wrap.find('.conn-log')
  274. }
  275. function render() {
  276. jqNodes['total_selected'].text(state.selectedTableTwo.length);
  277. if (state.selectedTableTwo.length > 0) {
  278. jQuery(props.stateClearSelectedBtnId).show();
  279. } else {
  280. jQuery(props.stateClearSelectedBtnId).hide();
  281. }
  282. jqNodes['state_log'].text(JSON.stringify(state));
  283. switch (state.filterSelected) {
  284. case 'yes':
  285. jqNodes['filter_yes'].addClass('active');
  286. jqNodes['filter_no'].removeClass('active');
  287. jqNodes['filter_clear'].removeClass('active');
  288. break;
  289. case 'no':
  290. jqNodes['filter_yes'].removeClass('active');
  291. jqNodes['filter_no'].addClass('active');
  292. jqNodes['filter_clear'].removeClass('active');
  293. break;
  294. case 'clear':
  295. jqNodes['filter_yes'].removeClass('active');
  296. jqNodes['filter_no'].removeClass('active');
  297. jqNodes['filter_clear'].addClass('active');
  298. break;
  299. }
  300. }
  301. function action__selectTableOneRow(pk) {
  302. state.selectedTableOne = pk;
  303. render();
  304. }
  305. function action__unselectTableOneRow() {
  306. state.selectedTableOne = null;
  307. render();
  308. }
  309. function action__selectTableTwoRow(pk) {
  310. var idx = state.selectedTableTwo.indexOf(pk);
  311. if (-1 === idx) state.selectedTableTwo.push(pk);
  312. else console.log("Error selectedTableTwo - should be not set");
  313. render();
  314. }
  315. function action__unselectTableTwoRow(pk) {
  316. var idx = state.selectedTableTwo.indexOf(pk);
  317. if (-1 === idx) state.selectedTableTwo.push(pk);
  318. else state.selectedTableTwo.splice(idx, 1);
  319. render();
  320. }
  321. function action__clearSelection() {
  322. state.selectedTableTwo = [];
  323. jQuery(props.tableTwoId).find('tbody').children('.info').removeClass('info');
  324. render();
  325. }
  326. function action__filterSet(fltr) {
  327. state.filterSelected = fltr;
  328. render();
  329. // TODO: ajax load tableTwo based on filter
  330. }
  331. jQuery(document).on(props.jsEventNamespace + ':tableOne:click', function(e, n, payload) {
  332. var n$ = jQuery(n);
  333. console.log('event '+props.jsEventNamespace+':tableOne:click', n, payload);
  334. jQuery.notify('tableOne row clicked [' + payload.props.primary_key + ']', 'info');
  335. if (n$.hasClass('info')) {
  336. n$.removeClass('info');
  337. action__unselectTableOneRow();
  338. } else {
  339. n$.parent().children('.info').removeClass('info');
  340. n$.addClass('info');
  341. action__selectTableOneRow(payload.props.primary_key);
  342. }
  343. });
  344. jQuery(document).on(props.jsEventNamespace + ':tableTwo:click', function(e, n, payload) {
  345. var n$ = jQuery(n);
  346. console.log('event '+props.jsEventNamespace+':tableTwo:click', n, payload);
  347. jQuery.notify('tableTwo row clicked [' + payload.props.primary_key + ']', 'info');
  348. if (n$.hasClass('info')) {
  349. n$.removeClass('info');
  350. action__unselectTableTwoRow(payload.props.primary_key);
  351. } else {
  352. n$.addClass('info');
  353. action__selectTableTwoRow(payload.props.primary_key);
  354. }
  355. });
  356. jQuery(document).on(props.jsEventNamespace + ':clearSelection:click', function(e, n, payload) {
  357. action__clearSelection();
  358. });
  359. jqNodes['filter_yes'].on('click', function(e) {
  360. action__filterSet('yes');
  361. });
  362. jqNodes['filter_no'].on('click', function(e) {
  363. action__filterSet('no');
  364. });
  365. jqNodes['filter_clear'].on('click', function(e) {
  366. action__filterSet('clear');
  367. });
  368. })();
  369. </script>
  370. <?php
  371. }
  372. }