AclStruct.php 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545
  1. <?php
  2. Lib::loadClass('RouteBase');
  3. Lib::loadClass('Router');
  4. Lib::loadClass('Response');
  5. Lib::loadClass('UI');
  6. Lib::loadClass('SchemaFactory');
  7. class Route_Storage_AclStruct extends RouteBase {
  8. public function handleAuth() {
  9. if (!User::logged()) {
  10. User::authByRequest();
  11. }
  12. }
  13. public function defaultAction() { // objectStructAction
  14. UI::gora();
  15. UI::menu();
  16. // Router::getRoute('Storage')->navView(); // TODO: header like in Storage_AclUsage
  17. UI::startTag('div', [ 'class' => 'container-fluid' ]);
  18. try {
  19. $namespace = V::get('namespace', '', $_GET);
  20. if (empty($namespace)) throw new Exception("Missing param namespace");
  21. if ('setFieldRefConfig' === V::get('_postTask', '', $_POST)) {
  22. $field = V::get('field', '', $_POST);
  23. $source = V::get('source', '', $_POST);
  24. switch ($source) {
  25. case 'view':
  26. $refSelect = ACL::generateRefSelectSqlByFlatRelationCache($namespace, $field);
  27. ACL::setRefSource($namespace, $field, 'view', $refSelect);
  28. break;
  29. case 'table': ACL::setRefSource($namespace, $field, 'table'); break;
  30. }
  31. }
  32. if ('preview' === V::get('_postTask', '', $_POST)) {
  33. try {
  34. $item = SchemaFactory::loadDefaultObject('SystemObject')->getItem($namespace, [ 'propertyName' => '*,field' ]);
  35. $localFields = array_filter($item['field'], function ($field) {
  36. return $field['isLocal'];
  37. });
  38. $refFields = array_filter($item['field'], function ($field) {
  39. return 'ref:' === substr($field['xsdType'], 0, 4);
  40. });
  41. $activeRefFields = array_filter($refFields, function ($field) {
  42. $refNamespace = str_replace(['__x3A__', ':'], '/', substr($field['xsdType'], strlen('ref:')));
  43. return (1 == DB::getPDO()->fetchValue("
  44. select t.isObjectActive
  45. from `CRM_#CACHE_ACL_OBJECT` t
  46. where t.`namespace` = '{$refNamespace}'
  47. "));
  48. });
  49. $query = [ 'cols' => array_merge(
  50. array_map(
  51. function ($field) {
  52. return $field['fieldNamespace'];
  53. }, $localFields
  54. ),
  55. array_map(
  56. function ($field) {
  57. return "{$field['fieldNamespace']}/*";
  58. }, $activeRefFields
  59. )
  60. ) ];
  61. DBG::nicePrint($query, '$query');
  62. $previewItems = ACL::getAclByNamespace($namespace)->buildQuery($query)->getItems([
  63. 'limit' => 3
  64. ]);
  65. DBG::nicePrint($previewItems, 'items with ref limit 3');
  66. } catch (Exception $e) {
  67. DBG::log($e);
  68. UI::alert('danger', $e->getMessage());
  69. }
  70. }
  71. $item = SchemaFactory::loadDefaultObject('SystemObject')->getItem($namespace, [ 'propertyName' => '*,field' ]);
  72. usort($item['field'], function ($a, $b) {
  73. if ($a['fieldNamespace'] > $b['fieldNamespace']) return 1;
  74. if ($a['fieldNamespace'] < $b['fieldNamespace']) return -1;
  75. return 0;
  76. });
  77. echo UI::h('details', ['style'=>"margin-bottom:24px; padding:0 10px; background-color:#eee", 'open' => "open"], [
  78. UI::h('summary', ['style'=>"font-size:1.4em; line-height:2em; cursor:pointer; outline:none"], [
  79. "Struktura obiektu '{$namespace}' ",
  80. // UI::h('small', ['style'=>"font-size:0.8em; font-style:italic; color:#aaa"], " więcej...")
  81. ]),
  82. UI::h('div', ['style'=>"padding:4px 24px; border-top:1px solid #fff"], [
  83. UI::h('span', ['style'=>"margin-right:12px"], [
  84. ( ($item['idZasob'] > 0)
  85. ? UI::h('span', [ 'title' => "Nr zasobu '{$item['idZasob']}'" ], "Nr zasobu [{$item['idZasob']}]")
  86. : UI::h('span', [ 'title' => "Brak nr zasobu - dodaj do zasobów" ], [
  87. UI::hButtonAjax("+ do zasobów", 'addAclObjectToZasobyAjax', [
  88. 'class' => "btn btn-xs btn-primary",
  89. 'href' => Router::getRoute('Storage')->getLink('addAclObjectToZasobyAjax'),
  90. 'data' => [
  91. 'idStorage' => $item['idDatabase'],
  92. 'namespace' => $item['namespace'],
  93. ]
  94. ])
  95. ])
  96. ),
  97. ]),
  98. UI::h('span', ['style'=>"margin:0 12px"], [
  99. ( ($item['isObjectActive'] > 0)
  100. ? UI::h('span', [ 'class' => "label label-success", 'title' => "Namespace active" ], "Active")
  101. : UI::h('span', [ 'title' => "Namespace not active" ], [
  102. ($item['idZasob'] > 0)
  103. ? UI::hButtonAjax("Aktywuj", 'activateObjectAjax', [
  104. 'class' => "btn btn-xs btn-primary",
  105. 'href' => Router::getRoute('Storage')->getLink('activateObjectAjax'),
  106. 'data' => [
  107. 'namespace' => $item['namespace'],
  108. ]
  109. ])
  110. : '',
  111. ])
  112. ),
  113. ]),
  114. UI::h('a', [
  115. 'href' => "index.php?_route=ViewTableAjax&namespace={$item['namespace']}",
  116. 'class' => "btn btn-sm btn-link"
  117. ], "Przeglądaj tabelę"),
  118. ( ($item['idZasob'] > 0)
  119. ? UI::h('a', [
  120. 'href' => "procesy5.php?task=CRM_LISTA_ZASOBOW&filtr_id={$item['idZasob']}&filtr_ids=%2B&filtr_ob=%2B",
  121. 'class' => "btn btn-sm btn-link",
  122. 'title' => "Struktura tabeli w drzewie zasobów"
  123. ], "Zasoby")
  124. : ''
  125. ),
  126. ( ($item['idZasob'] > 0)
  127. ? UI::h('a', [
  128. 'href' => "index.php?FUNCTION_INIT=PROCES_MENU&HEADER_NOT_INIT=YES&_task=PROCES_FOR_TABLE&tblId={$item['idZasob']}",
  129. 'class' => "btn btn-sm btn-link",
  130. 'title' => "Procesy dla aktualnie przeglądanej tabeli"
  131. ], "Procesy")
  132. : ''
  133. ),
  134. UI::h('a', [
  135. 'href' => Router::getRoute('Storage')->getLink('objectReinstall', ['namespace' => $item['namespace']]),
  136. 'class' => 'btn btn-sm btn-link', 'style' => "color:#f00",
  137. 'title' => "Zainstaluje ponownie obiekt"
  138. ], "reinstall object"),
  139. UI::h('a', [
  140. 'href' => Router::getRoute('Storage_AclUsage')->getLink('', [ 'namespace' => $item['namespace'] ]),
  141. 'class' => "btn btn-sm btn-link",
  142. 'title' => "Uprawnienia - analiza użycia komórek w procesach"
  143. ], "Uprawnienia (analiza użycia)"),
  144. UI::hButtonPost("(podgląd z relacjami)", [
  145. 'data' => [
  146. '_postTask' => 'preview'
  147. ],
  148. 'class' => 'btn btn-sm btn-link', 'style' => "font-style:italic",
  149. 'title' => "Podgląd kilku ostatnich obiektów wraz z relacjami"
  150. ]),
  151. ])
  152. ]);
  153. $thisGetLink = [Router::getRoute('Storage'), 'getLink'];
  154. { // not installed ref
  155. $refFields = array_filter($item['field'], function ($field) {
  156. return 'ref:' === substr($field['xsdType'], 0, 4);
  157. });
  158. UI::table([
  159. 'caption' => UI::h('span', [], "Obiekty powiązane (TODO backRef)"),
  160. 'rows' => array_map(function ($field) use ($thisGetLink) {
  161. $refNamespace = str_replace(['__x3A__', ':'], '/', substr($field['xsdType'], strlen('ref:')));
  162. $isInstalled = (1 == DB::getPDO()->fetchValue("
  163. select t.isObjectActive
  164. from `CRM_#CACHE_ACL_OBJECT` t
  165. where t.`namespace` = '{$refNamespace}'
  166. "));
  167. $refSource = null;
  168. if ($isInstalled) {
  169. try {
  170. $refTable = ACL::getRefTable($field['objectNamespace'], $field['fieldNamespace']);
  171. DBG::log($refTable, 'array', "getRefTable('{$field['objectNamespace']}', '{$field['fieldNamespace']}')");
  172. $refSource = ACL::getRefSource($field['objectNamespace'], $field['fieldNamespace']);
  173. DBG::log($refSource, 'array', "ACL::getRefSource('{$field['objectNamespace']}', '{$field['fieldNamespace']}')");
  174. } catch (Exception $e) {
  175. DBG::log($e);
  176. }
  177. }
  178. return [
  179. 'fieldName' => $field['fieldNamespace'],
  180. // 'xsdType' => $field['xsdType'], // always === "ref:{$field['fieldNamespace']}"
  181. 'ref object' => UI::h('a', [
  182. 'class' => "btn btn-xs btn-link",
  183. 'href' => $thisGetLink('objectStruct', [ 'namespace' => $refNamespace ])
  184. ], "objectStruct ({$refNamespace})"),
  185. 'ref source' => UI::h('div', [],
  186. (null === $refSource)
  187. ? [ "ref object not installed" ] // TODO: link to install? is table struct
  188. : [
  189. // UI::hButtonAjax("Tabela ref", "setFieldRefConfig", [
  190. // 'class' => "btn btn-xs btn-default" . ( 'table' === $refSource ? ' disabled' : '' ),
  191. // 'href' => $thisGetLink('setFieldRefConfig'),
  192. // 'data' => [ 'namespace' => $refNamespace, 'field' => $field['fieldNamespace'], 'do' => 'table' ]
  193. // ]),
  194. // UI::hButtonAjax("Widok (cache)", "setFieldRefConfig", [
  195. // 'title' => "Według flat_relation_cache",
  196. // 'class' => "btn btn-xs btn-default" . ( 'view' === $refSource ? ' disabled' : '' ),
  197. // 'href' => $thisGetLink('setFieldRefConfig'),
  198. // 'data' => [ 'namespace' => $refNamespace, 'field' => $field['fieldNamespace'], 'do' => 'view' ]
  199. // ]),
  200. UI::hButtonPost("Tabela ref", [
  201. 'title' => "Według wygenerowanej tabeli REF",
  202. 'class' => "btn btn-xs btn-default" . ( 'table' === $refSource ? ' disabled' : '' ),
  203. // 'href' => $thisGetLink('setFieldRefConfig'),
  204. 'data' => [ 'namespace' => $refNamespace, 'field' => $field['fieldNamespace'], '_postTask' => 'setFieldRefConfig', 'source' => 'table' ]
  205. ]),
  206. UI::hButtonPost("Widok (cache)", [
  207. 'title' => "Według flat_relation_cache",
  208. 'class' => "btn btn-xs btn-default" . ( 'view' === $refSource ? ' disabled' : '' ),
  209. // 'href' => $thisGetLink('setFieldRefConfig'),
  210. 'data' => [ 'namespace' => $refNamespace, 'field' => $field['fieldNamespace'], '_postTask' => 'setFieldRefConfig', 'source' => 'view' ]
  211. ]),
  212. ]
  213. ),
  214. '@class' => ($isInstalled) ? "success" : "danger",
  215. ]; // TODO: link to install object
  216. }, $refFields)
  217. ]);
  218. }
  219. UI::table([
  220. 'caption' => UI::h('span', [], [
  221. UI::h('span', [ 'style' => "margin-right:6px;color:#000" ], "Struktura obiektu '{$item['namespace']}'"),
  222. ]),
  223. 'rows' => array_map(function ($field) use ($item, $thisGetLink) {
  224. $tblItem = []; foreach ($field as $k => $v) $tblItem[$k] = $v;
  225. $tblItem['namespace'] = UI::h('span', [], [
  226. UI::h('span', ['style' => "color:#aaa"], substr($field['namespace'], 0, strlen($field['objectNamespace']) + 1)),
  227. UI::h('span', ['style' => "color:#000"], substr($field['namespace'], strlen($field['objectNamespace']) + 1)),
  228. ]);
  229. $tblItem['idZasob'] = ($field['idZasob'] > 0)
  230. ? $field['idZasob']
  231. : (
  232. ($item['idZasob'] > 0)
  233. ? UI::hButtonAjax("+ do zasobów", 'addFieldToZasobyAjax', [
  234. 'class' => "btn btn-xs btn-primary",
  235. 'href' => $thisGetLink('addFieldToZasobyAjax'),
  236. 'data' => [
  237. 'namespace' => $item['namespace'],
  238. 'fieldNamespace' => $field['namespace'],
  239. ]
  240. ])
  241. : UI::h('span', ['title'=>"Brak Nr zasobu dla obiektu", 'class'=>"btn btn-xs btn-danger"], "Brak nr zasobu obiektu")
  242. )
  243. ;
  244. unset($tblItem['objectNamespace']);
  245. unset($tblItem['fieldNamespace']);
  246. return $tblItem;
  247. }, $item['field'])
  248. ]);
  249. UI::hButtonAjaxOnResponse('addFieldToZasobyAjax', /* payload, n */ "
  250. if (!payload.type) return false
  251. if (payload.body && payload.body.id && payload.body.id > 0) { // if ('success' == payload.type) {
  252. n.parentNode.replaceChild(document.createTextNode(payload.body.id), n)
  253. }
  254. jQuery.notify(payload.msg, payload.type)
  255. ");
  256. UI::hButtonAjaxOnResponse('addAclObjectToZasobyAjax', /* payload, n */ "
  257. if (!payload.type) return false
  258. if ('success' === payload.type || 'info' === payload.type) {
  259. if (payload.body && payload.body.id && payload.body.id > 0) {
  260. n.parentNode.replaceChild(document.createTextNode(payload.body.id), n)
  261. } else {
  262. console.log('TODO: addAclObjectToZasobyAjax unknown response', payload);
  263. }
  264. window.location.reload()
  265. }
  266. ");
  267. UI::hButtonAjaxOnResponse('activateObjectAjax', /* payload, n */ "
  268. jQuery.notify(payload.msg, payload.type)
  269. if (!payload.type) return false
  270. if ('success' === payload.type || 'info' === payload.type) {
  271. if (payload.body && payload.body.isObjectActive && payload.body.isObjectActive > 0) {
  272. n.parentNode.replaceChild(document.createTextNode('Active'), n)
  273. } else {
  274. console.log('TODO: activateObjectAjax unknown response', payload);
  275. }
  276. }
  277. ");
  278. if ($item['isObjectActive']) {
  279. echo UI::hButtonAjax("Dodaj podstawowy proces dla obiektu '{$item['namespace']}' - read only (TODO)", 'addObjectBaseProcesAjax', [
  280. 'class' => "btn btn-xs btn-default",
  281. 'href' => Router::getRoute('Storage')->getLink('addObjectBaseProcesAjax'),
  282. 'data' => [ 'namespace' => $item['namespace'] ]
  283. ]);
  284. UI::hButtonAjaxOnResponse('addObjectBaseProcesAjax', /* payload, n */ "
  285. jQuery.notify(payload.msg, payload.type)
  286. ");
  287. }
  288. DBG::nicePrint($item, '$item');
  289. } catch (Exception $e) {
  290. UI::alert('danger', "Error #" . $e->getCode() . "|" . $e->getLine() . ": " . $e->getMessage());
  291. DBG::log($e);
  292. }
  293. UI::endTag('div'); // .container-fluid
  294. UI::dol();
  295. }
  296. public function tableStructAction() {
  297. UI::gora();
  298. UI::menu();
  299. // Router::getRoute('Storage')->navView(); // TODO: header like in Storage_AclUsage
  300. try {
  301. $idStorage = V::get('idStorage', 0, $_REQUEST, 'int');
  302. if (empty($idStorage)) throw new Exception("Missing id storage");
  303. $storageList = Router::getRoute('Storage')->getStorageList();
  304. if (empty($storageList)) throw new Exception("No storage defined");
  305. if (!array_key_exists($idStorage, $storageList)) throw new Exception("Storage not exists");
  306. $tblName = V::get('table', '', $_REQUEST, 'word');
  307. if (empty($tblName)) throw new Exception("No table name");
  308. $storagePdo = DB::getStorage($idStorage);
  309. $tblStruct = $storagePdo->getTableStruct($tblName);
  310. $idTable = Router::getRoute('Storage')->fetchTableId($idStorage, $tblName);
  311. if ($idTable <= 0) {
  312. UI::alert('warning', "Zasob tabela '{$tblName}' nie istnieje");// TODO: add p5UI btn
  313. DBG::table("tblStruct", $tblStruct, __CLASS__, __FUNCTION__, __LINE__);
  314. throw new Exception("Zasob tabela '{$tblName}' nie istnieje");
  315. }
  316. $cellZasobList = array();
  317. foreach (DB::getPDO()->fetchAllByKey("
  318. select z.ID, z.`DESC`, z.`TYPE` as ZASOB_TYPE, z.A_STATUS
  319. from CRM_LISTA_ZASOBOW z
  320. where z.PARENT_ID = '{$idTable}'
  321. ", $key = 'DESC') as $ind => $row) {
  322. $cellZasobList[strtolower($ind)] = $row;
  323. }
  324. $emptyItem = array();
  325. $emptyItem['name'] = '';
  326. $emptyItem['id_zasob'] = '';
  327. $emptyItem['zasob_type'] = '';
  328. $emptyItem['uwagi'] = '';
  329. $emptyItem['type'] = '';
  330. $emptyItem['is_nullable'] = '';
  331. $emptyItem['default_value'] = '';
  332. $emptyItem['default_is_null'] = '';
  333. $emptyItem['max_length'] = '';
  334. $emptyItem['num_precision'] = '';
  335. $emptyItem['num_scale'] = '';
  336. $emptyItem['char_encoding'] = '';
  337. $emptyItem['char_collation'] = '';
  338. $emptyItem['extra'] = '';
  339. $emptyItem['raw_storage_type'] = '';
  340. $tableList = array();
  341. foreach ($tblStruct as $row) {
  342. $cellName = $row['name'];
  343. $tblItem = V::cloneArray($emptyItem);
  344. $tblItem['name'] = $cellName;
  345. foreach ($row as $fldName => $fldVal) {
  346. if (array_key_exists($fldName, $tblItem)) $tblItem[$fldName] = $fldVal;
  347. }
  348. $tblItem['uwagi'] = '';
  349. $lowerCellName = strtolower($cellName);
  350. $tblZasob = V::get($lowerCellName, '', $cellZasobList);
  351. if ($tblZasob) {
  352. $cellZasobList[$lowerCellName]['_checked'] = true;
  353. $tblItem['id_zasob'] = $tblZasob['ID'];
  354. $tblItem['zasob_type'] = $tblZasob['ZASOB_TYPE'];
  355. } else {
  356. $tblItem['uwagi'] .= '!Zasob';//'TODO: ADD ZASOB';
  357. $ajaxAddZasobLink = Router::getRoute('Storage')->getLink('addCellToZasoby', [ 'idStorage' => $idStorage, 'tblName' => $tblName, 'cellName' => $cellName]);
  358. $onClick = "return p5UI__ButtonAjax(this, 'p5UIBtnAjax:Storage:addCellToZasoby', { href: '{$ajaxAddZasobLink}' })";
  359. $tblItem['id_zasob'] = '<a onclick="'.$onClick.'" class="btn btn-xs btn-primary" href="#">TODO: ADD ZASOB</a>';
  360. }
  361. $tableList[] = $tblItem;
  362. }
  363. foreach ($cellZasobList as $cellName => $row) {
  364. if ('URL_ACTION' == $row['ZASOB_TYPE']) continue;
  365. if (!$row['_checked']) {
  366. $tblItem = V::cloneArray($emptyItem);
  367. $tblItem['name'] = $cellName;
  368. $tblItem['id_zasob'] = $row['ID'];
  369. $tblItem['zasob_type'] = $row['ZASOB_TYPE'];
  370. $tblItem['uwagi'] = '!DB';//'TODO: nie istnieje w bazie danych';
  371. $tableList[] = $tblItem;
  372. }
  373. }
  374. usort($tableList, function($rowA, $rowB) {
  375. $a = $rowA['name']; $b = $rowB['name'];
  376. if ('ID' == $a) return -1;
  377. if ('ID' == $b) return 1;
  378. if ($a == $b) return 0;
  379. $a1 = substr($a, 0, 1); $b1 = substr($b, 0, 1);
  380. if (('_' == $a1 || '_' == $b1) && $a1 != $b1) {
  381. return ($a1 < $b1) ? 1 : -1;
  382. }
  383. return ($a < $b) ? -1 : 1;
  384. });
  385. UI::table([
  386. 'caption' => UI::h('span', [], [
  387. "Komórki [{$idTable}] ",
  388. UI::h('a', [
  389. 'href' => "index.php?_route=ViewTableAjax&namespace=default_db/{$tblName}",
  390. 'class' => "btn btn-md btn-link"
  391. ], "Przeglądaj tabelę"),
  392. UI::h('a', [
  393. 'href' => "procesy5.php?task=CRM_LISTA_ZASOBOW&filtr_id={$idTable}&filtr_ids=%2B&filtr_ob=%2B",
  394. 'class' => "btn btn-md btn-link",
  395. 'title' => "Struktura aktualnie przeglądanej tabeli"
  396. ], "Zasoby"),
  397. UI::h('a', [
  398. 'href' => "index.php?FUNCTION_INIT=PROCES_MENU&HEADER_NOT_INIT=YES&_task=PROCES_FOR_TABLE&tblId={$idTable}",
  399. 'class' => "btn btn-md btn-link",
  400. 'title' => "Procesy dla aktualnie przeglądanej tabeli"
  401. ], "Procesy"),
  402. UI::h('a', [
  403. 'href' => Router::getRoute('Storage_AclUsage')->getLink('', [ 'namespace' => "default_db/{$tblName}" ]),
  404. 'class' => "btn btn-md btn-link",
  405. 'title' => "Uprawnienia - analiza użycia komórek w procesach"
  406. ], "Uprawnienia (analiza użycia)"),
  407. ]),
  408. 'cols' => array_keys($emptyItem),
  409. 'rows' => $tableList
  410. ]);
  411. echo UI::h('script', [], "
  412. jQuery(document).on('p5UIBtnAjax:Storage:addCellToZasoby:click', function(e, n, payload) {
  413. console.log('event p5UIBtnAjax:Storage:addCellToZasoby:click', n, payload);
  414. });
  415. jQuery(document).on('p5UIBtnAjax:Storage:addCellToZasoby:ajaxLoaded', function(e, n, payload) {
  416. console.log('event p5UIBtnAjax:Storage:addCellToZasoby:ajaxLoaded', n, payload);
  417. if ('success' == payload.type && payload.body && payload.body.id > 0) {
  418. var cellUwagiJQNode = jQuery(n).parents('td').next('td');
  419. cellUwagiJQNode.text(cellUwagiJQNode.text().replace('!Zasob', ''))
  420. jQuery(n).parents('td').text(payload.body.id);
  421. jQuery(n).remove();
  422. }
  423. jQuery.notify(payload.msg, payload.type);
  424. });
  425. ");
  426. $ajaxAddZasobLink = Router::getRoute('Storage')->getLink('addGeomEtykietaCells', [ 'idStorage' => $idStorage, 'tblName' => $tblName]);
  427. $onClick = "return p5UI__ButtonAjax(this, 'p5UIBtnAjax:Storage:addGeomEtykietaCells', { href: '{$ajaxAddZasobLink}' })";
  428. UI::tag('a', ['onclick'=>$onClick, 'class'=>"btn btn-xs btn-default", 'href'=>"#"], "Dodaj komórki etykiet", true);
  429. echo "<i>(<code>`etykieta_x`</code>, <code>`etykieta_y`</code>, <code>`etykieta_obrot`</code>)</i>";
  430. echo UI::h('script', [], "
  431. jQuery(document).on('p5UIBtnAjax:Storage:addGeomEtykietaCells:ajaxLoaded', function(e, n, payload) {
  432. console.log('event p5UIBtnAjax:Storage:addGeomEtykietaCells:ajaxLoaded', n, payload);
  433. if ('success' == payload.type && payload.body && payload.body.id > 0) {
  434. var cellUwagiJQNode = jQuery(n).parents('td').next('td');
  435. cellUwagiJQNode.text(cellUwagiJQNode.text().replace('!Zasob', ''))
  436. jQuery(n).parents('td').text(payload.body.id);
  437. jQuery(n).remove();
  438. }
  439. jQuery.notify(payload.msg, payload.type);
  440. });
  441. ");
  442. $tableActions = array_filter($cellZasobList, function ($row) {
  443. return ('URL_ACTION' == $row['ZASOB_TYPE']);
  444. });
  445. UI::table([
  446. 'caption' => "tableActions",
  447. // 'cols' => array_keys($emptyItem),
  448. 'rows' => array_map(function ($item) {
  449. $sqlIdAction = DB::getPDO()->quote($item['ID'], PDO::PARAM_INT);
  450. $args = DB::getPDO()->fetchAll("
  451. select z.`DESC`
  452. , a.ID as ALIAS_ID, a.`DESC` as ALIAS_DESC, a.OPIS as ALIAS_OPIS
  453. from CRM_LISTA_ZASOBOW z
  454. left join CRM_LISTA_ZASOBOW a on(a.ID = z.ALIAS_ID)
  455. where z.PARENT_ID = {$sqlIdAction}
  456. and z.`TYPE` = 'PARAM_IN'
  457. ");
  458. $definitionArgs = DB::getPDO()->fetchAll("
  459. select p.ID, p.`DESC`
  460. from CRM_LISTA_ZASOBOW z
  461. join CRM_LISTA_ZASOBOW d on(d.ID = z.ALIAS_ID)
  462. left join CRM_LISTA_ZASOBOW p on(p.PARENT_ID = d.ID)
  463. where z.ID = {$sqlIdAction}
  464. and p.`TYPE` = 'PARAM_IN'
  465. ");
  466. $flatDefinitionArgs = implode(";", array_map(function ($arg) {
  467. return "{$arg['ID']}={$arg['DESC']}";
  468. }, $definitionArgs));
  469. return [
  470. 'label' => DB::getPDO()->fetchValue(" select z.OPIS from CRM_LISTA_ZASOBOW z where z.ID = {$sqlIdAction} ") . " " .
  471. UI::h('i', [
  472. 'class' => "glyphicon glyphicon-pencil",
  473. 'style' => "cursor:pointer",
  474. 'onClick' => "return Storage__tableStruct__editActionLabel(this, {$sqlIdAction})"], ''),
  475. 'args' => implode("<br>&", array_map(function ($item) {
  476. return (NULL === $item['ALIAS_ID'])
  477. ? $item['DESC']
  478. : "{$item['DESC']}=" . '{$row["' . $item['ALIAS_DESC'] . '"]}';// TODO: add rmParam btn
  479. }, $args)) . " " .
  480. UI::h('i', [
  481. 'class' => "glyphicon glyphicon-plus-sign",
  482. 'style' => "cursor:pointer",
  483. 'title' => "Dodaj PARAM_IN",
  484. 'onClick' => "return Storage__tableStruct__addParamAction(this, {$sqlIdAction}, '{$flatDefinitionArgs}')"], ''),
  485. // 'args_info' => '<pre>' . var_export($args, true) . '</pre>',
  486. 'ID' => $item['ID'],
  487. 'DESC' => $item['DESC'],
  488. 'A_STATUS' => $item['A_STATUS'],
  489. 'definition args' => implode("", array_map(function ($item) {
  490. return '<div style="white-space:nowrap">' . "[{$item['ID']}] {$item['DESC']}" . '</div>';
  491. }, $definitionArgs)),
  492. ];
  493. }, $tableActions)
  494. ]);
  495. echo UI::h('button', [
  496. 'onClick'=>"Storage__tableStruct__addAction()",
  497. 'class'=>"btn btn-xs btn-default"
  498. ], "Dodaj Akcję");
  499. echo UI::h('link', ['rel'=>"stylesheet", 'type'=>"text/css", 'href'=>"static/sweetalert2.min.css"]);
  500. echo UI::h('script', ['src'=>"static/sweetalert2.min.js"]);
  501. echo UI::h('style', [], "
  502. .swal2-radio.p5-swal-radio-as-list { text-align:left }
  503. .swal2-radio.p5-swal-radio-as-list > label { display:block; margin-left:20px }
  504. ");
  505. UI::inlineJS(__FILE__ . '.tableActions.js', [
  506. 'ID_STORAGE' => $idStorage,
  507. 'TABLE_NAME' => $tblName,
  508. 'FETCH_URL' => Router::getRoute('Storage')->getLink('fetchActionListAjax'),
  509. 'ADD_ACTION_URL' => Router::getRoute('Storage')->getLink('addActionAjax')
  510. ]);
  511. echo '<hr>';
  512. $ajaxAddBaseProcesLink = Router::getRoute('Storage')->getLink('addTableBaseProces', [ 'idStorage' => $idStorage, 'tblName' => $tblName ]);
  513. $onClick = "return p5UI__ButtonAjax(this, 'p5UIBtnAjax:Storage:addTableBaseProces', { href: '{$ajaxAddBaseProcesLink}' })";
  514. UI::tag('a', ['onclick'=>$onClick, 'class'=>"btn btn-xs btn-default", 'href'=>"#"], "Dodaj podstawowy proces dla tabeli '{$tblName}' - read only", true);
  515. echo UI::h('script', [], "
  516. jQuery(document).on('p5UIBtnAjax:Storage:addTableBaseProces:ajaxLoaded', function(e, n, payload) {
  517. jQuery.notify(payload.msg, payload.type);
  518. });
  519. ");
  520. } catch (Exception $e) {
  521. UI::alert('danger', "Error #" . $e->getCode() . "|" . $e->getLine() . ": " . $e->getMessage());
  522. }
  523. UI::dol();
  524. }
  525. }