AclStruct.php 54 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358
  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. function handleAuth() {
  9. if (!User::logged()) {
  10. User::authByRequest();
  11. }
  12. }
  13. function defaultAction() {
  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. // [idZasob] => 25872
  22. // [idDatabase] => 36
  23. // [namespace] => default_db/CRM_PROCES/CRM_PROCES
  24. // [_rootTableName] => CRM_PROCES
  25. // [_type] => AntAcl
  26. // [hasStruct] => 1
  27. // [isStructInstalled] => 1
  28. // [isObjectActive] => 1
  29. // [description] =>
  30. // [name] => CRM_PROCES
  31. // [nsPrefix] => default_db__x3A__CRM_PROCES
  32. // [typeName] => default_db__x3A__CRM_PROCES:CRM_PROCES
  33. // [reinstallLink] => https://biuro.biall-net.pl/dev-pl/se-master/index.php?_route=Storage_AclReinstall&namespace=default_db/CRM_PROCES/CRM_PROCES
  34. if ('_activateTableAclPostTask' === V::get('_postTask', '', $_POST)) {
  35. try {
  36. $ret = Router::getRoute('Storage')->activateTableAclAjax([ 'namespace' => $namespace ]);
  37. if (!empty($ret) && 'success' == $ret['type']) UI::alert('success', $ret['msg']);
  38. } catch (Exception $e) {
  39. UI::alert('danger', $e->getMessage());
  40. }
  41. }
  42. if ('_deactivateObjectPostTask' === V::get('_postTask', '', $_POST)) {
  43. try {
  44. $ret = Router::getRoute('Storage')->deactivateObjectAjax([ 'namespace' => $namespace ]);
  45. if (!empty($ret) && 'success' == $ret['type']) UI::alert('success', $ret['msg']);
  46. } catch (Exception $e) {
  47. UI::alert('danger', $e->getMessage());
  48. }
  49. }
  50. $item = SchemaFactory::loadDefaultObject('SystemObject')->getItem($namespace, [ 'propertyName' => '*,field' ]);
  51. switch ($item['_type']) {
  52. case 'TableAcl': $this->tableStructView($item, $item['name'], $item['idDatabase']); break;
  53. case 'AntAcl': $this->objectStructView($item); break;
  54. case 'StorageAcl': $this->objectStructView($item); break;
  55. default: throw new Exception("Not implemented type"); break;
  56. }
  57. } catch (Exception $e) {
  58. UI::alert('danger', "Error #" . $e->getCode() . "|" . $e->getLine() . ": " . $e->getMessage());
  59. DBG::log($e);
  60. }
  61. UI::endTag('div'); // .container-fluid
  62. UI::dol();
  63. }
  64. function tableStructAction() {
  65. UI::gora();
  66. UI::menu();
  67. // Router::getRoute('Storage')->navView(); // TODO: header like in Storage_AclUsage
  68. try {
  69. $idStorage = V::get('idStorage', 0, $_REQUEST, 'int');
  70. if (empty($idStorage)) throw new Exception("Missing id storage");
  71. $storageList = Router::getRoute('Storage')->getStorageList();
  72. if (empty($storageList)) throw new Exception("No storage defined");
  73. if (!array_key_exists($idStorage, $storageList)) throw new Exception("Storage not exists");
  74. $tblName = V::get('table', '', $_REQUEST, 'word');
  75. if (empty($tblName)) throw new Exception("No table name");
  76. $item = SchemaFactory::loadDefaultObject('SystemObject')->getItem($namespace, [ 'propertyName' => '*,field' ]);
  77. $this->tableStructView($item, $tblName, $idStorage);
  78. } catch (Exception $e) {
  79. UI::alert('danger', "Error #" . $e->getCode() . "|" . $e->getLine() . ": " . $e->getMessage());
  80. }
  81. UI::dol();
  82. }
  83. public function objectStructureAction() { // objectStructAction
  84. UI::gora();
  85. UI::menu();
  86. // Router::getRoute('Storage')->navView(); // TODO: header like in Storage_AclUsage
  87. UI::startTag('div', [ 'class' => 'container-fluid' ]);
  88. try {
  89. $namespace = V::get('namespace', '', $_GET);
  90. if (empty($namespace)) throw new Exception("Missing param namespace");
  91. $item = SchemaFactory::loadDefaultObject('SystemObject')->getItem($namespace, [ 'propertyName' => '*,field' ]);
  92. $this->objectStructView($item);
  93. } catch (Exception $e) {
  94. UI::alert('danger', "Error #" . $e->getCode() . "|" . $e->getLine() . ": " . $e->getMessage());
  95. DBG::log($e);
  96. }
  97. UI::endTag('div'); // .container-fluid
  98. UI::dol();
  99. }
  100. public function tableStructView($item, $tblName, $idStorage) {
  101. $storagePdo = DB::getStorage($idStorage);
  102. $tblStruct = $storagePdo->getTableStruct($tblName);
  103. $idTable = Router::getRoute('Storage')->fetchTableId($idStorage, $tblName);
  104. if ($idTable <= 0) {
  105. UI::alert('warning', "Zasob tabela '{$tblName}' nie istnieje");// TODO: add p5UI btn
  106. DBG::table("tblStruct", $tblStruct, __CLASS__, __FUNCTION__, __LINE__);
  107. throw new Exception("Zasob tabela '{$tblName}' nie istnieje");
  108. }
  109. $cellZasobList = array();
  110. foreach (DB::getPDO()->fetchAllByKey("
  111. select z.ID, z.`DESC`, z.`TYPE` as ZASOB_TYPE, z.A_STATUS, z.SORT_PRIO
  112. from CRM_LISTA_ZASOBOW z
  113. where z.PARENT_ID = '{$idTable}'
  114. ", $key = 'DESC') as $ind => $row) {
  115. $cellZasobList[strtolower($ind)] = $row;
  116. }
  117. $emptyItem = array();
  118. $emptyItem['sort'] = null;
  119. $emptyItem['name'] = '';
  120. $emptyItem['id_zasob'] = '';
  121. $emptyItem['zasob_type'] = '';
  122. $emptyItem['uwagi'] = '';
  123. $emptyItem['type'] = '';
  124. $emptyItem['is_nullable'] = '';
  125. $emptyItem['default_value'] = '';
  126. $emptyItem['default_is_null'] = '';
  127. $emptyItem['max_length'] = '';
  128. $emptyItem['num_precision'] = '';
  129. $emptyItem['num_scale'] = '';
  130. $emptyItem['char_encoding'] = '';
  131. $emptyItem['char_collation'] = '';
  132. $emptyItem['extra'] = '';
  133. $emptyItem['raw_storage_type'] = '';
  134. $tableList = array();
  135. foreach ($tblStruct as $row) {
  136. $cellName = $row['name'];
  137. $tblItem = V::cloneArray($emptyItem);
  138. $tblItem['name'] = $cellName;
  139. foreach ($row as $fldName => $fldVal) {
  140. if (array_key_exists($fldName, $tblItem)) $tblItem[$fldName] = $fldVal;
  141. }
  142. $tblItem['uwagi'] = '';
  143. $lowerCellName = strtolower($cellName);
  144. $tblZasob = V::get($lowerCellName, '', $cellZasobList);
  145. if ($tblZasob) {
  146. $cellZasobList[$lowerCellName]['_checked'] = true;
  147. $tblItem['id_zasob'] = $tblZasob['ID'];
  148. $tblItem['zasob_type'] = $tblZasob['ZASOB_TYPE'];
  149. $tblItem['sort'] = $tblZasob['SORT_PRIO'];
  150. } else {
  151. $tblItem['uwagi'] .= '!Zasob';//'TODO: ADD ZASOB';
  152. $ajaxAddZasobLink = Router::getRoute('Storage')->getLink('addCellToZasoby', [ 'idStorage' => $idStorage, 'tblName' => $tblName, 'cellName' => $cellName]);
  153. $onClick = "return p5UI__ButtonAjax(this, 'p5UIBtnAjax:Storage:addCellToZasoby', { href: '{$ajaxAddZasobLink}' })";
  154. $tblItem['id_zasob'] = '<a onclick="'.$onClick.'" class="btn btn-xs btn-primary" href="#">TODO: ADD ZASOB</a>';
  155. }
  156. $tableList[] = $tblItem;
  157. }
  158. foreach ($cellZasobList as $cellName => $row) {
  159. if ('URL_ACTION' == $row['ZASOB_TYPE']) continue;
  160. if (!$row['_checked']) {
  161. $tblItem = V::cloneArray($emptyItem);
  162. $tblItem['name'] = $cellName;
  163. $tblItem['id_zasob'] = $row['ID'];
  164. $tblItem['zasob_type'] = $row['ZASOB_TYPE'];
  165. $tblItem['uwagi'] = '!DB';//'TODO: nie istnieje w bazie danych';
  166. $tableList[] = $tblItem;
  167. }
  168. }
  169. { // sortBy
  170. $sortByArgName = 'sortBy';
  171. $sortByCol = V::get($sortByArgName, 'name', $_GET);
  172. $sortByDir = V::get("{$sortByArgName}Dir", 'asc', $_GET);
  173. if ('name' === $sortByCol) {
  174. usort($tableList, function($rowA, $rowB) {
  175. $a = $rowA['name']; $b = $rowB['name'];
  176. // if ('ID' == $a) return -1;
  177. // if ('ID' == $b) return 1;
  178. if ($a == $b) return 0;
  179. $a1 = substr($a, 0, 1); $b1 = substr($b, 0, 1);
  180. if (('_' == $a1 || '_' == $b1) && $a1 != $b1) {
  181. return ($a1 < $b1) ? 1 : -1;
  182. }
  183. return ($a < $b) ? -1 : 1;
  184. });
  185. }
  186. else if ('sort' === $sortByCol) {
  187. usort($tableList, function ($a, $b) use ($sortByDir) {
  188. if (null === $a['sort'] && null === $b['sort']) return 0;
  189. if (null === $a['sort'] && null != $b['sort']) return 1;
  190. if (null !== $a['sort'] && null === $b['sort']) return -1;
  191. if ($a['sort'] > $b['sort']) return 'asc' === $sortByDir ? 1 : -1;
  192. if ($a['sort'] < $b['sort']) return 'asc' === $sortByDir ? -1 : 1;
  193. return 0;
  194. });
  195. }
  196. echo UI::h('style', [ 'type' => "text/css" ], "
  197. .ta-ordering { cursor:pointer }
  198. .ta-ordering-desc:after { content:\"\\e252\"; font-family:\"Glyphicons Halflings\"; line-height:1; margin:0 0 0 3px; display:inline-block; color:#bbb }
  199. .ta-ordering-asc:after { content:\"\\e253\"; font-family:\"Glyphicons Halflings\"; line-height:1; margin:0 0 0 3px; display:inline-block; color:#bbb }
  200. .ta-sortable-item { }
  201. .ta-sortable-item-handle { cursor:pointer }
  202. ");
  203. echo UI::h('script', [ 'src' => "static/URI.js" ]);
  204. echo UI::h('script', [], "
  205. function p5UI_table_sortBy_get(n, argName, colName, dir) {
  206. var newUri = URI(window.location.href).setQuery(argName, colName).setQuery(argName+'Dir', dir).build().toString();
  207. window.location.href = newUri
  208. }
  209. ");
  210. }
  211. echo UI::h('details', ['style'=>"margin-bottom:24px; padding:0 10px; background-color:#eee", 'open' => "open"], [
  212. UI::h('summary', ['style'=>"font-size:1.4em; line-height:2em; cursor:pointer; outline:none"], [
  213. "Struktura obiektu '{$item['namespace']}' ",
  214. ]),
  215. UI::h('div', ['style'=>"padding:4px 24px; border-top:1px solid #fff"], [
  216. UI::h('span', ['style'=>"margin-right:12px"], [
  217. ( ($item['idZasob'] > 0)
  218. ? UI::h('span', [ 'title' => "Nr zasobu '{$item['idZasob']}'" ], "Nr zasobu [{$item['idZasob']}]")
  219. : UI::h('span', [ 'title' => "Brak nr zasobu - dodaj do zasobów" ], [
  220. UI::hButtonAjax("+ do zasobów", 'addAclObjectToZasobyAjax', [
  221. 'class' => "btn btn-xs btn-primary",
  222. 'href' => Router::getRoute('Storage')->getLink('addAclObjectToZasobyAjax'),
  223. 'data' => [
  224. 'idStorage' => $item['idDatabase'],
  225. 'namespace' => $item['namespace'],
  226. ]
  227. ])
  228. ])
  229. ),
  230. ]),
  231. UI::h('span', ['style'=>"margin:0 12px"], [
  232. ( ($item['isObjectActive'] > 0)
  233. ? UI::h('span', [ 'class' => "label label-success", 'title' => "Namespace active" ], "Active")
  234. : UI::h('span', [ 'title' => "Namespace not active" ], [
  235. ($item['idZasob'] > 0)
  236. ? UI::hButtonPost("Aktywuj", [
  237. 'class' => "btn btn-xs btn-primary",
  238. 'data' => [
  239. '_postTask' => '_activateTableAclPostTask',
  240. 'namespace' => $item['namespace'],
  241. ]
  242. ])
  243. : '',
  244. ])
  245. ),
  246. ( ($item['isObjectActive'] > 0)
  247. ? UI::h('span', [ 'title' => "Namespace is active" ], [
  248. UI::hButtonPost("Wyłącz", [
  249. 'class' => "btn btn-xs btn-default",
  250. 'data' => [
  251. '_postTask' => '_deactivateObjectPostTask',
  252. 'namespace' => $item['namespace'],
  253. ]
  254. ])
  255. ])
  256. : ''
  257. ),
  258. ]),
  259. UI::h('a', [
  260. 'href' => "index.php?_route=ViewTableAjax&namespace={$item['namespace']}",
  261. 'class' => "btn btn-sm btn-link"
  262. ], "Przeglądaj tabelę"),
  263. ( ($item['idZasob'] > 0)
  264. ? UI::h('a', [
  265. 'href' => "procesy5.php?task=CRM_LISTA_ZASOBOW&filtr_id={$item['idZasob']}&filtr_ids=%2B&filtr_ob=%2B",
  266. 'class' => "btn btn-sm btn-link",
  267. 'title' => "Struktura tabeli w drzewie zasobów"
  268. ], "Zasoby")
  269. : ''
  270. ),
  271. ( ($item['idZasob'] > 0)
  272. ? UI::h('a', [
  273. 'href' => "index.php?FUNCTION_INIT=PROCES_MENU&HEADER_NOT_INIT=YES&_task=PROCES_FOR_TABLE&tblId={$item['idZasob']}",
  274. 'class' => "btn btn-sm btn-link",
  275. 'title' => "Procesy dla aktualnie przeglądanej tabeli"
  276. ], "Procesy")
  277. : ''
  278. ),
  279. // UI::h('a', [
  280. // 'href' => Router::getRoute('Storage_AclReinstall')->getLink('', [ 'namespace' => $item['namespace'] ]),
  281. // 'class' => 'btn btn-sm btn-link', 'style' => "color:#f00",
  282. // 'title' => "Zainstaluje ponownie obiekt"
  283. // ], "reinstall object"),
  284. UI::h('a', [
  285. 'href' => Router::getRoute('Storage_AclUsage')->getLink('', [ 'namespace' => $item['namespace'] ]),
  286. 'class' => "btn btn-sm btn-link",
  287. 'title' => "Uprawnienia - analiza użycia komórek w procesach"
  288. ], "Uprawnienia (analiza użycia)"),
  289. UI::h('a', [
  290. 'href' => Router::getRoute('WfsJsRequestPanel')->getLink('', [ 'namespace' => $item['namespace'] ]),
  291. 'class' => "btn btn-sm btn-link",
  292. 'title' => "JavaScript WFS Panel"
  293. ], "JavaScript WFS Panel"),
  294. UI::h('a', [
  295. 'href' => Router::getRoute('Storage_TestXsd')->getLink('tableXsd', [ 'idStorage' => $idStorage, 'table' => "{$tblName}" ]),
  296. 'class' => "btn btn-md btn-link",
  297. ], "xsd"),
  298. ])
  299. ]);
  300. $listFieldNames = array_map(V::makePick('name'), $tableList);
  301. if ('_setTableAclPrimaryKey' === V::get('_postTask', '', $_POST)) {
  302. $primaryKey = V::get('primryKey', '', $_POST);
  303. DBG::nicePrint($primaryKey, "\$primaryKey='{$primaryKey}'");
  304. if (!in_array($primaryKey, $listFieldNames)) {
  305. UI::alert('danger', "Wybrano niewłaściwe pole");
  306. } else {
  307. UI::alert('warning', "TODO: ustaw '{$primaryKey}'");
  308. SchemaFactory::loadDefaultObject('SystemObject')->updateItem([
  309. 'namespace' => $item['namespace'],
  310. 'primaryKey' => $primaryKey,
  311. ]);
  312. $item = SchemaFactory::loadDefaultObject('SystemObject')->getItem($item['namespace'], [ 'propertyName' => '*,field' ]);
  313. }
  314. }
  315. $primaryKey = $item['primaryKey'];
  316. echo UI::h('form', [
  317. 'class' => "form-inline",
  318. 'style' => "margin:12px 0",
  319. 'method' => "POST",
  320. ], [
  321. UI::h('label', [], "Primary Key:"),
  322. UI::h('select', [ 'type' => "select", 'class' => "form-control", 'name' => "primryKey" ],
  323. array_merge(
  324. [ UI::h('option', [ 'value' => "-1" ], " [ wybierz ] ") ],
  325. array_map(function ($itemTableList) use ($primaryKey) {
  326. return UI::h('option', array_merge(
  327. [ 'value' => $itemTableList['name'] ],
  328. ($primaryKey === $itemTableList['name'])
  329. ? [ 'selected' => "selected" ]
  330. : []
  331. ), $itemTableList['name']);
  332. }, $tableList)
  333. )
  334. ),
  335. UI::h('input', [ 'type' => "hidden", 'name' => "_postTask", 'value' => "_setTableAclPrimaryKey" ]),
  336. UI::h('input', [ 'type' => "submit", 'class' => "btn btn-default", 'value' => "Zapisz" ]),
  337. ]);
  338. if (!$item['primaryKey']) UI::alert('danger', "Nie ustawiono primaryKey");
  339. UI::table([
  340. '__html_id' => 'struct_table',
  341. 'caption' => "Struktura tabeli {$tblName} [{$idTable}]",
  342. 'cols_label' => [
  343. 'sort' => UI::h('nobr', [
  344. 'class' => "ta-ordering" . ('sort' === $sortByCol ? " ta-ordering-" . ( 'asc' === $sortByDir ? 'asc' : 'desc' ) : '' ),
  345. 'onClick' => "return p5UI_table_sortBy_get(this, '{$sortByArgName}', 'sort', '" . ('sort' === $sortByCol ? ( 'asc' === $sortByDir ? 'desc' : 'asc' ) : 'asc' ) . "')",
  346. 'title' => "Sortuj wg pola SORT_PRIO z zasobów",
  347. ], "sort"),
  348. 'name' => UI::h('nobr', [
  349. 'class' => "ta-ordering" . ('name' === $sortByCol ? " ta-ordering-" . ( 'asc' === $sortByDir ? 'asc' : 'desc' ) : '' ),
  350. 'onClick' => "return p5UI_table_sortBy_get(this, '{$sortByArgName}', 'name', '" . ('name' === $sortByCol ? ( 'asc' === $sortByDir ? 'desc' : 'asc' ) : 'asc' ) . "')",
  351. 'title' => "Sortuj wg nazwy",
  352. ], "namespace"),
  353. ],
  354. 'cols' => array_keys($emptyItem),
  355. 'rows' => array_map(function ($item) use ($sortByCol) {
  356. if ('sort' === $sortByCol && null !== $item['sort'] && !empty($item['id_zasob'])) {
  357. $item['@class'] = "ta-sortable-item";
  358. $item['@class[sort]'] = "ta-sortable-item-handle";
  359. $item['@data']['sort_prio'] = $item['sort'];
  360. $item['@data']['id_zasob'] = $item['id_zasob'];
  361. $item['sort'] = ":: {$item['sort']}";
  362. }
  363. return $item;
  364. }, $tableList),
  365. ]);
  366. echo UI::h('script', [], "
  367. jQuery(document).on('p5UIBtnAjax:Storage:addCellToZasoby:click', function(e, n, payload) {
  368. console.log('event p5UIBtnAjax:Storage:addCellToZasoby:click', n, payload);
  369. });
  370. jQuery(document).on('p5UIBtnAjax:Storage:addCellToZasoby:ajaxLoaded', function(e, n, payload) {
  371. console.log('event p5UIBtnAjax:Storage:addCellToZasoby:ajaxLoaded', n, payload);
  372. if ('success' == payload.type && payload.body && payload.body.id > 0) {
  373. var cellUwagiJQNode = jQuery(n).parents('td').next('td');
  374. cellUwagiJQNode.text(cellUwagiJQNode.text().replace('!Zasob', ''))
  375. jQuery(n).parents('td').text(payload.body.id);
  376. jQuery(n).remove();
  377. }
  378. jQuery.notify(payload.msg, payload.type);
  379. });
  380. ");
  381. $ajaxAddZasobLink = Router::getRoute('Storage')->getLink('addGeomEtykietaCells', [ 'idStorage' => $idStorage, 'tblName' => $tblName]);
  382. $onClick = "return p5UI__ButtonAjax(this, 'p5UIBtnAjax:Storage:addGeomEtykietaCells', { href: '{$ajaxAddZasobLink}' })";
  383. UI::tag('a', ['onclick'=>$onClick, 'class'=>"btn btn-xs btn-default", 'href'=>"#"], "Dodaj komórki etykiet", true);
  384. echo "<i>(<code>`etykieta_x`</code>, <code>`etykieta_y`</code>, <code>`etykieta_obrot`</code>)</i>";
  385. echo UI::h('script', [], "
  386. jQuery(document).on('p5UIBtnAjax:Storage:addGeomEtykietaCells:ajaxLoaded', function(e, n, payload) {
  387. console.log('event p5UIBtnAjax:Storage:addGeomEtykietaCells:ajaxLoaded', n, payload);
  388. if ('success' == payload.type && payload.body && payload.body.id > 0) {
  389. var cellUwagiJQNode = jQuery(n).parents('td').next('td');
  390. cellUwagiJQNode.text(cellUwagiJQNode.text().replace('!Zasob', ''))
  391. jQuery(n).parents('td').text(payload.body.id);
  392. jQuery(n).remove();
  393. }
  394. jQuery.notify(payload.msg, payload.type);
  395. });
  396. ");
  397. $tableActions = array_filter($cellZasobList, function ($row) {
  398. return ('URL_ACTION' == $row['ZASOB_TYPE']);
  399. });
  400. UI::table([
  401. 'caption' => "tableActions",
  402. // 'cols' => array_keys($emptyItem),
  403. 'rows' => array_map(function ($item) {
  404. $sqlIdAction = DB::getPDO()->quote($item['ID'], PDO::PARAM_INT);
  405. $args = DB::getPDO()->fetchAll("
  406. select z.`DESC`
  407. , a.ID as ALIAS_ID, a.`DESC` as ALIAS_DESC, a.OPIS as ALIAS_OPIS
  408. from CRM_LISTA_ZASOBOW z
  409. left join CRM_LISTA_ZASOBOW a on(a.ID = z.ALIAS_ID)
  410. where z.PARENT_ID = {$sqlIdAction}
  411. and z.`TYPE` = 'PARAM_IN'
  412. ");
  413. $definitionArgs = DB::getPDO()->fetchAll("
  414. select p.ID, p.`DESC`
  415. from CRM_LISTA_ZASOBOW z
  416. join CRM_LISTA_ZASOBOW d on(d.ID = z.ALIAS_ID)
  417. left join CRM_LISTA_ZASOBOW p on(p.PARENT_ID = d.ID)
  418. where z.ID = {$sqlIdAction}
  419. and p.`TYPE` = 'PARAM_IN'
  420. ");
  421. $flatDefinitionArgs = implode(";", array_map(function ($arg) {
  422. return "{$arg['ID']}={$arg['DESC']}";
  423. }, $definitionArgs));
  424. return [
  425. 'label' => DB::getPDO()->fetchValue(" select z.OPIS from CRM_LISTA_ZASOBOW z where z.ID = {$sqlIdAction} ") . " " .
  426. UI::h('i', [
  427. 'class' => "glyphicon glyphicon-pencil",
  428. 'style' => "cursor:pointer",
  429. 'onClick' => "return Storage__tableStruct__editActionLabel(this, {$sqlIdAction})"], ''),
  430. 'args' => implode("<br>&", array_map(function ($item) {
  431. return (NULL === $item['ALIAS_ID'])
  432. ? $item['DESC']
  433. : "{$item['DESC']}=" . '{$row["' . $item['ALIAS_DESC'] . '"]}';// TODO: add rmParam btn
  434. }, $args)) . " " .
  435. UI::h('i', [
  436. 'class' => "glyphicon glyphicon-plus-sign",
  437. 'style' => "cursor:pointer",
  438. 'title' => "Dodaj PARAM_IN",
  439. 'onClick' => "return Storage__tableStruct__addParamAction(this, {$sqlIdAction}, '{$flatDefinitionArgs}')"], ''),
  440. // 'args_info' => '<pre>' . var_export($args, true) . '</pre>',
  441. 'ID' => $item['ID'],
  442. 'DESC' => $item['DESC'],
  443. 'A_STATUS' => $item['A_STATUS'],
  444. 'definition args' => implode("", array_map(function ($item) {
  445. return '<div style="white-space:nowrap">' . "[{$item['ID']}] {$item['DESC']}" . '</div>';
  446. }, $definitionArgs)),
  447. ];
  448. }, $tableActions)
  449. ]);
  450. echo UI::h('button', [
  451. 'onClick'=>"Storage__tableStruct__addAction()",
  452. 'class'=>"btn btn-xs btn-default"
  453. ], "Dodaj Akcję");
  454. echo UI::h('link', ['rel'=>"stylesheet", 'type'=>"text/css", 'href'=>"static/sweetalert2.min.css"]);
  455. echo UI::h('script', ['src'=>"static/sweetalert2.min.js"]);
  456. echo UI::h('style', [], "
  457. .swal2-radio.p5-swal-radio-as-list { text-align:left }
  458. .swal2-radio.p5-swal-radio-as-list > label { display:block; margin-left:20px }
  459. ");
  460. UI::inlineJS(__FILE__ . '.tableActions.js', [
  461. 'ID_STORAGE' => $idStorage,
  462. 'TABLE_NAME' => $tblName,
  463. 'FETCH_URL' => Router::getRoute('Storage')->getLink('fetchActionListAjax'),
  464. 'ADD_ACTION_URL' => Router::getRoute('Storage')->getLink('addActionAjax')
  465. ]);
  466. echo '<hr>';
  467. $ajaxAddBaseProcesLink = Router::getRoute('Storage')->getLink('addTableBaseProces', [ 'idStorage' => $idStorage, 'tblName' => $tblName ]);
  468. $onClick = "return p5UI__ButtonAjax(this, 'p5UIBtnAjax:Storage:addTableBaseProces', { href: '{$ajaxAddBaseProcesLink}' })";
  469. UI::tag('a', ['onclick'=>$onClick, 'class'=>"btn btn-xs btn-default", 'href'=>"#"], "Dodaj podstawowy proces dla tabeli '{$tblName}' - read only", true);
  470. echo UI::h('script', [], "
  471. jQuery(document).on('p5UIBtnAjax:Storage:addTableBaseProces:ajaxLoaded', function(e, n, payload) {
  472. jQuery.notify(payload.msg, payload.type);
  473. });
  474. ");
  475. if ('sort' === $sortByCol) {
  476. echo UI::h('script', [], "
  477. jQuery(document).ready(function (){
  478. var tblNode$ = jQuery('#struct_table > tbody')
  479. var getOrder = function () {
  480. var orderIds = []
  481. jQuery('#struct_table > tbody').children('.ta-sortable-item').each(function (idx, trNode) {
  482. orderIds.push(jQuery(trNode).data('id_zasob'))
  483. })
  484. return orderIds
  485. }
  486. var sortOrder = getOrder()
  487. console.log('sortOrder - init', sortOrder)
  488. tblNode$.sortable({
  489. axis: 'y',
  490. handle: '.ta-sortable-item-handle',
  491. items: '.ta-sortable-item',
  492. update: function (event, ui) {
  493. sortOrder = getOrder()
  494. tblNode$.sortable('disable')
  495. tblNode$.find('.ta-sortable-item-handle').css({color:'silver'})
  496. console.log('TODO: disable sortable while ajax')
  497. // window.setTimeout(function () {
  498. // tblNode$.find('.ta-sortable-item-handle').css({color:'black'})
  499. // console.log('TODO: ajax fetch result')
  500. // tblNode$.sortable('enable')
  501. // tblNode$.sortable('cancel')
  502. // }, 1000)
  503. window.fetch(
  504. URI(window.location.href)
  505. .setSearch('_task', 'updateAntAclSortAjax')
  506. .setSearch('idZasobOrder', sortOrder)
  507. .build().toString(),
  508. {
  509. method: 'POST',
  510. headers: {
  511. 'Content-Type': 'application/x-www-form-urlencoded' // query string
  512. },
  513. credentials: 'same-origin',
  514. body: JSON.stringify({
  515. namespace: URI.parseQuery(window.location.search).namespace,
  516. sortBy: '{$sortByCol}',
  517. sortByDir: '{$sortByDir}',
  518. sortOrder: sortOrder,
  519. })
  520. }
  521. ).then(function(response) {
  522. return response.json()
  523. }).then(function(payload) {
  524. console.log('updateAntAclSortAjax response', payload);
  525. tblNode$.sortable('enable')
  526. if ('success' !== payload.type) {
  527. tblNode$.sortable('cancel')
  528. }
  529. tblNode$.sortable('enable')
  530. tblNode$.find('.ta-sortable-item-handle').css({color:'black'})
  531. p5UI__notifyAjaxCallback({
  532. type: payload.type || 'error',
  533. msg: payload.msg || 'Request error'
  534. });
  535. if ('success' === payload.type) {
  536. window.location.reload(true)
  537. }
  538. }).catch(function(e) {
  539. tblNode$.sortable('enable')
  540. tblNode$.sortable('cancel')
  541. tblNode$.find('.ta-sortable-item-handle').css({color:'black'})
  542. p5UI__notifyAjaxCallback({
  543. type: 'error',
  544. msg: 'Request error ' + e
  545. });
  546. })
  547. }
  548. });
  549. });
  550. ");
  551. }
  552. }
  553. public function objectStructView($item) {
  554. $namespace = $item['namespace'];
  555. { // sortBy
  556. $sortByArgName = 'sortBy';
  557. $sortByCol = V::get($sortByArgName, 'namespace', $_GET);
  558. $sortByDir = V::get("{$sortByArgName}Dir", 'asc', $_GET);
  559. { // add SORT_PRIO
  560. $item['field'] = array_map(function ($field) {
  561. $field['SORT_PRIO'] = ($field['idZasob'] > 0)
  562. ? DB::getPDO()->fetchValue("
  563. select z.SORT_PRIO
  564. from CRM_LISTA_ZASOBOW z
  565. where z.ID = :id
  566. ", [ ':id' => $field['idZasob'] ])
  567. : null
  568. ;
  569. return $field;
  570. }, $item['field']);
  571. }
  572. if ('namespace' === $sortByCol) {
  573. usort($item['field'], function ($a, $b) use ($sortByDir) {
  574. if ($a['fieldNamespace'] > $b['fieldNamespace']) return 'asc' === $sortByDir ? 1 : -1;
  575. if ($a['fieldNamespace'] < $b['fieldNamespace']) return 'asc' === $sortByDir ? -1 : 1;
  576. return 0;
  577. });
  578. }
  579. else if ('sort' === $sortByCol) {
  580. usort($item['field'], function ($a, $b) use ($sortByDir) {
  581. if (null === $a['SORT_PRIO'] && null === $b['SORT_PRIO']) return 0;
  582. if (null === $a['SORT_PRIO'] && null != $b['SORT_PRIO']) return 1;
  583. if (null !== $a['SORT_PRIO'] && null === $b['SORT_PRIO']) return -1;
  584. if ($a['SORT_PRIO'] > $b['SORT_PRIO']) return 'asc' === $sortByDir ? 1 : -1;
  585. if ($a['SORT_PRIO'] < $b['SORT_PRIO']) return 'asc' === $sortByDir ? -1 : 1;
  586. return 0;
  587. });
  588. }
  589. echo UI::h('style', [ 'type' => "text/css" ], "
  590. .ta-ordering { cursor:pointer }
  591. .ta-ordering-desc:after { content:\"\\e252\"; font-family:\"Glyphicons Halflings\"; line-height:1; margin:0 0 0 3px; display:inline-block; color:#bbb }
  592. .ta-ordering-asc:after { content:\"\\e253\"; font-family:\"Glyphicons Halflings\"; line-height:1; margin:0 0 0 3px; display:inline-block; color:#bbb }
  593. .ta-sortable-item { }
  594. .ta-sortable-item-handle { cursor:pointer }
  595. ");
  596. echo UI::h('script', [ 'src' => "static/URI.js" ]);
  597. echo UI::h('script', [], "
  598. function p5UI_table_sortBy_get(n, argName, colName, dir) {
  599. var newUri = URI(window.location.href).setQuery(argName, colName).setQuery(argName+'Dir', dir).build().toString();
  600. window.location.href = newUri
  601. }
  602. ");
  603. }
  604. if ('setFieldRefConfig' === V::get('_postTask', '', $_POST)) {
  605. $objectNamespace = $namespace;
  606. $childTypeName = V::get('field', '', $_POST);
  607. $source = V::get('source', '', $_POST);
  608. $toUpdateField = array_filter($item['field'], function ($field) use ($childTypeName) { return ($childTypeName === $field['fieldNamespace']); });
  609. $toUpdateField = (!empty($toUpdateField)) ? reset($toUpdateField) : null;
  610. if (!$toUpdateField) throw new Exception("Field not found '{$childTypeName}'");
  611. $typeField = Type_Field::build($toUpdateField);
  612. $refConfig = RefConfig::fetch($objectNamespace, $childTypeName);
  613. switch ($source) {
  614. case 'view': RefConfig::installRefView($objectNamespace, $childTypeName, $typeField, $refConfig); break;
  615. case 'table': RefConfig::installRefTable($objectNamespace, $childTypeName, $typeField, $refConfig); break;
  616. }
  617. }
  618. if ('preview' === V::get('_postTask', '', $_POST)) {
  619. try {
  620. $item = SchemaFactory::loadDefaultObject('SystemObject')->getItem($namespace, [ 'propertyName' => '*,field' ]);
  621. $localFields = array_filter($item['field'], function ($field) {
  622. return $field['isLocal'];
  623. });
  624. $refFields = array_filter($item['field'], function ($field) {
  625. return 'ref:' === substr($field['xsdType'], 0, 4);
  626. });
  627. $activeRefFields = array_filter($refFields, function ($field) {
  628. $refNamespace = str_replace(['__x3A__', ':'], '/', substr($field['xsdType'], strlen('ref:')));
  629. return (1 == DB::getPDO()->fetchValue("
  630. select t.isObjectActive
  631. from `CRM_#CACHE_ACL_OBJECT` t
  632. where t.`namespace` = '{$refNamespace}'
  633. "));
  634. });
  635. $previewItems = ACL::getAclByNamespace($namespace)->buildQuery([])->getItems([
  636. 'limit' => 5
  637. ]);
  638. DBG::nicePrint($previewItems, 'items (default query) - preview (limit 5)');
  639. $query = [ 'cols' => array_merge(
  640. array_map(
  641. function ($field) {
  642. return $field['fieldNamespace'];
  643. }, $localFields
  644. ),
  645. array_map(
  646. function ($field) {
  647. return "{$field['fieldNamespace']}/*";
  648. }, $activeRefFields
  649. )
  650. ) ];
  651. DBG::nicePrint($query, 'items with ref/* - query');
  652. $previewItems = ACL::getAclByNamespace($namespace)->buildQuery($query)->getItems([
  653. 'limit' => 5
  654. ]);
  655. DBG::nicePrint($previewItems, 'items with ref/* - preview (limit 5)');
  656. $query = [ 'cols' => array_merge(
  657. array_map(
  658. function ($field) {
  659. return $field['fieldNamespace'];
  660. }, $localFields
  661. ),
  662. array_map(
  663. function ($field) {
  664. return "{$field['fieldNamespace']}";
  665. }, $activeRefFields
  666. )
  667. ) ];
  668. DBG::nicePrint($query, 'items with ref as xlink - query');
  669. $previewItems = ACL::getAclByNamespace($namespace)->buildQuery($query)->getItems([
  670. 'limit' => 5
  671. ]);
  672. DBG::nicePrint($previewItems, 'items with ref as xlink - preview (limit 5)');
  673. } catch (Exception $e) {
  674. DBG::log($e);
  675. UI::alert('danger', $e->getMessage());
  676. }
  677. }
  678. echo UI::h('div', ['style'=>"margin-bottom:24px; padding:0 10px; background-color:#eee", 'open' => "open"], [
  679. UI::h('div', [], [
  680. UI::h('a', [
  681. 'class' => "btn btn-link",
  682. 'href' => Router::getRoute('Storage')->getLink('tableList', [ 'idStorage' => $item['idDatabase'] ]),
  683. ], "&laquo wróć do listy"),
  684. " ",
  685. UI::h('b', [ 'style' => "font-size:1.1em; line-height:2em" ], "Struktura obiektu '{$namespace}'"),
  686. // UI::h('small', ['style'=>"font-size:0.8em; font-style:italic; color:#aaa"], " więcej...")
  687. ]),
  688. UI::h('div', ['style'=>"padding:4px 24px; border-top:1px solid #fff"], [
  689. UI::h('span', ['style'=>"margin-right:12px"], [
  690. ( ($item['idZasob'] > 0)
  691. ? UI::h('span', [ 'title' => "Nr zasobu '{$item['idZasob']}'" ], "Nr zasobu [{$item['idZasob']}]")
  692. : UI::h('span', [ 'title' => "Brak nr zasobu - dodaj do zasobów" ], [
  693. UI::hButtonAjax("+ do zasobów", 'addAclObjectToZasobyAjax', [
  694. 'class' => "btn btn-xs btn-primary",
  695. 'href' => Router::getRoute('Storage')->getLink('addAclObjectToZasobyAjax'),
  696. 'data' => [
  697. 'idStorage' => $item['idDatabase'],
  698. 'namespace' => $item['namespace'],
  699. ]
  700. ])
  701. ])
  702. ),
  703. ]),
  704. UI::h('span', ['style'=>"margin:0 12px"], [
  705. ( ($item['isObjectActive'] > 0)
  706. ? UI::h('span', [ 'class' => "label label-success", 'title' => "Namespace active" ], "Active")
  707. : UI::h('span', [ 'title' => "Namespace not active" ], [
  708. ($item['idZasob'] > 0)
  709. ? UI::hButtonAjax("Aktywuj", 'activateObjectAjax', [
  710. 'class' => "btn btn-xs btn-primary",
  711. 'href' => Router::getRoute('Storage')->getLink('activateObjectAjax'),
  712. 'data' => [
  713. 'namespace' => $item['namespace'],
  714. ]
  715. ])
  716. : '',
  717. ])
  718. ),
  719. ]),
  720. UI::h('a', [
  721. 'href' => "index.php?_route=ViewTableAjax&namespace={$item['namespace']}",
  722. 'class' => "btn btn-sm btn-link"
  723. ], "Przeglądaj tabelę"),
  724. ( ($item['idZasob'] > 0)
  725. ? UI::h('a', [
  726. 'href' => "procesy5.php?task=CRM_LISTA_ZASOBOW&filtr_id={$item['idZasob']}&filtr_ids=%2B&filtr_ob=%2B",
  727. 'class' => "btn btn-sm btn-link",
  728. 'title' => "Struktura tabeli w drzewie zasobów"
  729. ], "Zasoby")
  730. : ''
  731. ),
  732. ( ($item['idZasob'] > 0)
  733. ? UI::h('a', [
  734. 'href' => "index.php?FUNCTION_INIT=PROCES_MENU&HEADER_NOT_INIT=YES&_task=PROCES_FOR_TABLE&tblId={$item['idZasob']}",
  735. 'class' => "btn btn-sm btn-link",
  736. 'title' => "Procesy dla aktualnie przeglądanej tabeli"
  737. ], "Procesy")
  738. : ''
  739. ),
  740. UI::h('a', [
  741. 'href' => Router::getRoute('Storage_AclReinstall')->getLink('', ['namespace' => $item['namespace']]),
  742. 'class' => 'btn btn-sm btn-link', 'style' => "color:#f00",
  743. 'title' => "Zainstaluje ponownie obiekt"
  744. ], "reinstall object"),
  745. UI::h('a', [
  746. 'href' => Router::getRoute('Storage_AclUsage')->getLink('', [ 'namespace' => $item['namespace'] ]),
  747. 'class' => "btn btn-sm btn-link",
  748. 'title' => "Uprawnienia - analiza użycia komórek w procesach"
  749. ], "Uprawnienia (analiza użycia)"),
  750. UI::h('a', [
  751. 'href' => Router::getRoute('WfsJsRequestPanel')->getLink('', [ 'namespace' => $item['namespace'] ]),
  752. 'class' => "btn btn-sm btn-link",
  753. 'title' => "JavaScript WFS Panel"
  754. ], "JavaScript WFS Panel"),
  755. UI::hButtonPost("(podgląd z relacjami)", [
  756. 'data' => [
  757. '_postTask' => 'preview'
  758. ],
  759. 'class' => 'btn btn-sm btn-link', 'style' => "font-style:italic",
  760. 'title' => "Podgląd kilku ostatnich obiektów wraz z relacjami"
  761. ]),
  762. ])
  763. ]);
  764. $thisGetLink = [ $this, 'getLink' ];
  765. { // not installed ref
  766. $refFields = array_filter($item['field'], function ($field) {
  767. return ('ref:' === substr($field['xsdType'], 0, 4) && $field['isActive']);
  768. });
  769. $nsSiblings = ACL::getNamespaceSiblings($item['namespace']);
  770. $siblingSelected = $item['namespace'];
  771. $baseUrl = $this->getLink();
  772. echo UI::h('h3', [], [
  773. "Obiekty powiązane",
  774. (empty($nsSiblings))
  775. ? ''
  776. : UI::h('small', [ 'class' => "pull-right" ],
  777. UI::h('select', [
  778. 'onChange' => "window.location.href='{$baseUrl}&namespace=' + this.value"
  779. ], array_map(function ($sibling) use ($siblingSelected) {
  780. return UI::h('option', array_merge(
  781. [ 'value' => $sibling ],
  782. ($siblingSelected === $sibling) ? [ 'selected' => "selected" ] : []
  783. ), $sibling);
  784. }, $nsSiblings))
  785. ),
  786. ]);
  787. UI::table([
  788. 'rows' => array_map(function ($backRef) use ($thisGetLink) {
  789. $refNamespace = $backRef['namespace'];
  790. $isInstalled = (1 == DB::getPDO()->fetchValue("
  791. select t.isObjectActive
  792. from `CRM_#CACHE_ACL_OBJECT` t
  793. where t.`namespace` = '{$refNamespace}'
  794. "));
  795. return [
  796. 'back ref namespace' => UI::h('a', [
  797. 'class' => "btn btn-xs btn-link",
  798. 'href' => $thisGetLink('', [ 'namespace' => $refNamespace ])
  799. ], "{$refNamespace}"),
  800. // 'idInstance' => $backRef['idInstance'],
  801. // 'isInstalled' => $isInstalled,
  802. '@class' => ($isInstalled) ? "success" : "danger",
  803. ];
  804. }, ACL::getBackRefList($item['namespace'])),
  805. ]);
  806. UI::table([
  807. 'rows' => array_map(function ($field) use ($thisGetLink) {
  808. $refNs = str_replace(['__x3A__', ':'], '/', substr($field['xsdType'], strlen('ref:')));
  809. $refNamespace = ACL::getBaseNamespace($refNs);
  810. $isInstalled = (1 == DB::getPDO()->fetchValue("
  811. select t.isObjectActive
  812. from `CRM_#CACHE_ACL_OBJECT` t
  813. where t.`namespace` = '{$refNamespace}'
  814. "));
  815. $refSource = null;
  816. if ($isInstalled) {
  817. try {
  818. $refTable = ACL::getRefTable($field['objectNamespace'], $field['fieldNamespace']);
  819. DBG::log($refTable, 'array', "getRefTable('{$field['objectNamespace']}', '{$field['fieldNamespace']}')");
  820. $refSource = ACL::getRefSource($field['objectNamespace'], $field['fieldNamespace']);
  821. DBG::log($refSource, 'array', "ACL::getRefSource('{$field['objectNamespace']}', '{$field['fieldNamespace']}')");
  822. } catch (Exception $e) {
  823. DBG::log($e);
  824. }
  825. }
  826. $labelRefSource = [
  827. 'table' => "Tabela",
  828. 'view' => "Widok",
  829. 'backRef' => "BackRef",
  830. ];
  831. return [
  832. 'child ref name' => $field['fieldNamespace'],
  833. // 'xsdType' => $field['xsdType'], // always === "ref:{$field['fieldNamespace']}"
  834. 'ref object' => UI::h('a', [
  835. 'class' => "btn btn-xs btn-link",
  836. 'href' => $thisGetLink('', [ 'namespace' => $refNamespace ])
  837. ], "{$refNs}"),
  838. 'ref source' => UI::h('div', [],
  839. (null === $refSource)
  840. ? [ "ref object not installed" ] // TODO: link to install? is table struct
  841. : [
  842. // UI::hButtonAjax("Tabela ref", "setFieldRefConfig", [
  843. // 'class' => "btn btn-xs btn-default" . ( 'table' === $refSource ? ' disabled' : '' ),
  844. // 'href' => $thisGetLink('setFieldRefConfig'),
  845. // 'data' => [ 'namespace' => $refNamespace, 'field' => $field['fieldNamespace'], 'do' => 'table' ]
  846. // ]),
  847. // UI::hButtonAjax("Widok (cache)", "setFieldRefConfig", [
  848. // 'title' => "Według flat_relation_cache",
  849. // 'class' => "btn btn-xs btn-default" . ( 'view' === $refSource ? ' disabled' : '' ),
  850. // 'href' => $thisGetLink('setFieldRefConfig'),
  851. // 'data' => [ 'namespace' => $refNamespace, 'field' => $field['fieldNamespace'], 'do' => 'view' ]
  852. // ]),
  853. $labelRefSource[$refSource] . ' ',
  854. ('view' === $refSource)
  855. ? UI::hButtonPost("Zmień na tabelę", [
  856. 'title' => "Według wygenerowanej tabeli REF",
  857. 'class' => "btn btn-xs btn-default" . ( 'table' === $refSource ? ' disabled' : '' ),
  858. // 'href' => $thisGetLink('setFieldRefConfig'),
  859. 'data' => [ 'namespace' => $refNamespace, 'field' => $field['fieldNamespace'], '_postTask' => 'setFieldRefConfig', 'source' => 'table' ]
  860. ])
  861. : '',
  862. ('table' === $refSource)
  863. ? UI::hButtonPost("Zmień na widok", [
  864. 'title' => "Według flat_relation_cache",
  865. 'class' => "btn btn-xs btn-default" . ( 'view' === $refSource ? ' disabled' : '' ),
  866. // 'href' => $thisGetLink('setFieldRefConfig'),
  867. 'data' => [ 'namespace' => $refNamespace, 'field' => $field['fieldNamespace'], '_postTask' => 'setFieldRefConfig', 'source' => 'view' ]
  868. ])
  869. : '',
  870. ]
  871. ),
  872. '@class' => ($isInstalled) ? "success" : "danger",
  873. ]; // TODO: link to install object
  874. }, $refFields)
  875. ]);
  876. }
  877. $thisGetLink = [ $this, 'getLink' ];
  878. UI::table([
  879. '__html_id' => 'struct_table',
  880. 'caption' => UI::h('span', [], [
  881. UI::h('span', [ 'style' => "margin-right:6px;color:#000" ], "Struktura obiektu '{$item['namespace']}'"),
  882. UI::h('code', [ 'style' => "margin-right:6px;color:#000" ], "(PrimaryKey: " . ($item['primaryKey'] ? $item['primaryKey'] : "Brak" ) . ")"),
  883. ]),
  884. // 'sortBy' => [
  885. // 'method' => 'get',
  886. // 'argName' => '_sortBy',
  887. // 'allow' => ['sort', 'namespace'],
  888. // 'default' => ['namespace', 'asc'],
  889. // ],
  890. 'cols_label' => [
  891. 'sort' => UI::h('nobr', [
  892. 'class' => "ta-ordering" . ('sort' === $sortByCol ? " ta-ordering-" . ( 'asc' === $sortByDir ? 'asc' : 'desc' ) : '' ),
  893. 'onClick' => "return p5UI_table_sortBy_get(this, '{$sortByArgName}', 'sort', '" . ('sort' === $sortByCol ? ( 'asc' === $sortByDir ? 'desc' : 'asc' ) : 'asc' ) . "')",
  894. 'title' => "Sortuj wg pola SORT_PRIO z zasobów",
  895. ], "sort"),
  896. 'namespace' => UI::h('nobr', [
  897. 'class' => "ta-ordering" . ('namespace' === $sortByCol ? " ta-ordering-" . ( 'asc' === $sortByDir ? 'asc' : 'desc' ) : '' ),
  898. 'onClick' => "return p5UI_table_sortBy_get(this, '{$sortByArgName}', 'namespace', '" . ('namespace' === $sortByCol ? ( 'asc' === $sortByDir ? 'desc' : 'asc' ) : 'asc' ) . "')",
  899. 'title' => "Sortuj wg nazwy pola",
  900. ], "namespace"),
  901. ],
  902. 'rows' => array_map(function ($field) use ($item, $thisGetLink, $sortByCol) {
  903. $tblItem = [];
  904. if ('sort' === $sortByCol && null !== $field['SORT_PRIO'] && !empty($field['idZasob'])) {
  905. $tblItem['@class'] = "ta-sortable-item";
  906. $tblItem['@class[sort]'] = "ta-sortable-item-handle";
  907. $tblItem['@data']['sort_prio'] = $field['SORT_PRIO'];
  908. $tblItem['@data']['id_zasob'] = $field['idZasob'];
  909. $field['SORT_PRIO'] = ":: {$field['SORT_PRIO']}";
  910. }
  911. $tblItem['sort'] = V::get('SORT_PRIO', null, $field);
  912. foreach ($field as $k => $v) {
  913. if ('SORT_PRIO' === $k) continue;
  914. $tblItem[$k] = $v;
  915. }
  916. $tblItem['namespace'] = UI::h('span', [], [
  917. UI::h('span', ['style' => "color:#aaa"], substr($field['namespace'], 0, strlen($field['objectNamespace']) + 1)),
  918. UI::h('span', ['style' => "color:#000"], substr($field['namespace'], strlen($field['objectNamespace']) + 1)),
  919. ]);
  920. $tblItem['idZasob'] = ($field['idZasob'] > 0)
  921. ? $field['idZasob']
  922. : (
  923. ($item['idZasob'] > 0)
  924. ? UI::hButtonAjax("+ do zasobów", 'addFieldToZasobyAjax', [
  925. 'class' => "btn btn-xs btn-primary",
  926. 'href' => $thisGetLink('addFieldToZasobyAjax'),
  927. 'data' => [
  928. 'namespace' => $item['namespace'],
  929. 'fieldNamespace' => $field['namespace'],
  930. ]
  931. ])
  932. : UI::h('span', ['title'=>"Brak Nr zasobu dla obiektu", 'class'=>"btn btn-xs btn-danger"], "Brak nr zasobu obiektu")
  933. )
  934. ;
  935. unset($tblItem['objectNamespace']);
  936. unset($tblItem['fieldNamespace']);
  937. return $tblItem;
  938. }, array_filter($item['field'], function ($field) { return $field['isActive']; }))
  939. ]);
  940. $removedFields = array_filter($item['field'], function ($field) { return !$field['isActive']; });
  941. if (!empty($removedFields)) {
  942. echo UI::h('details', [ 'style' => "margin-bottom:12px; padding:6px; background-color:#dedede; color:#000" ], [
  943. UI::h('summary', [ 'style' => "padding:0 3px; outline:none; cursor:pointer" ], "Pola w koszu (".count($removedFields).")"),
  944. UI::h('table', [ 'style' => "margin:6px 0 0 0; background-color:#fff; font-size:x-small", 'class' => "table table-bordered table-hover table-condensed" ], [
  945. UI::h('thead', [], [
  946. UI::h('tr', [], [
  947. UI::h('th', [], "#"),
  948. UI::h('th', [], "namespace"),
  949. UI::h('th', [], "idZasob"),
  950. UI::h('th', [], "xsdType"),
  951. UI::h('th', [], "xsdRestrictions"),
  952. UI::h('th', [], "appInfo"),
  953. UI::h('th', [], "minOccurs"),
  954. UI::h('th', [], "maxOccurs"),
  955. UI::h('th', [], "isActive"),
  956. ]),
  957. ]),
  958. UI::h('tbody', [], array_map(function ($field) use ($item, $thisGetLink) {
  959. return UI::h('tr', [], [
  960. UI::h('td', [], [
  961. UI::hButtonAjax("usuń", 'removeFieldFromTrashAjax', [
  962. 'class' => "btn btn-xs btn-danger",
  963. 'href' => $thisGetLink('removeFieldFromTrashAjax'),
  964. 'data' => [
  965. 'namespace' => $item['namespace'],
  966. 'fieldNamespace' => $field['namespace'],
  967. ]
  968. ])
  969. ]),
  970. UI::h('td', [], $field['fieldNamespace']),
  971. UI::h('td', [], [
  972. ($field['idZasob'] > 0)
  973. ? UI::h('span', [ 'class' => 'text-danger', 'title' => "Zasób zostanie usunięty" ], "{$field['idZasob']}")
  974. : UI::h('span', [ 'class' => 'text-muted' ], "brak")
  975. ]),
  976. UI::h('td', [], $field['xsdType']),
  977. UI::h('td', [], $field['xsdRestrictions']),
  978. UI::h('td', [], $field['appInfo']),
  979. UI::h('td', [], $field['minOccurs']),
  980. UI::h('td', [], $field['maxOccurs']),
  981. UI::h('td', [], $field['isActive']),
  982. ]);
  983. }, $removedFields)),
  984. ]),
  985. ]);
  986. }
  987. UI::hButtonAjaxOnResponse('removeFieldFromTrashAjax', /* payload, n */ "
  988. if (!payload.type) return false
  989. jQuery.notify(payload.msg, payload.type)
  990. if ('success' == payload.type) {
  991. var trJqNode = jQuery(n).closest('tr')
  992. var tbodyJqNode = trJqNode.parent()
  993. var detailsJqNode = trJqNode.closest('details')
  994. trJqNode.remove()
  995. if (!tbodyJqNode.children().length) {
  996. detailsJqNode.remove()
  997. }
  998. }
  999. ");
  1000. UI::hButtonAjaxOnResponse('addFieldToZasobyAjax', /* payload, n */ "
  1001. if (!payload.type) return false
  1002. if (payload.body && payload.body.id && payload.body.id > 0) { // if ('success' == payload.type) {
  1003. n.parentNode.replaceChild(document.createTextNode(payload.body.id), n)
  1004. }
  1005. jQuery.notify(payload.msg, payload.type)
  1006. ");
  1007. UI::hButtonAjaxOnResponse('addAclObjectToZasobyAjax', /* payload, n */ "
  1008. if (!payload.type) return false
  1009. if ('success' === payload.type || 'info' === payload.type) {
  1010. if (payload.body && payload.body.id && payload.body.id > 0) {
  1011. n.parentNode.replaceChild(document.createTextNode(payload.body.id), n)
  1012. } else {
  1013. console.log('TODO: addAclObjectToZasobyAjax unknown response', payload);
  1014. }
  1015. window.location.reload()
  1016. }
  1017. ");
  1018. UI::hButtonAjaxOnResponse('activateObjectAjax', /* payload, n */ "
  1019. jQuery.notify(payload.msg, payload.type)
  1020. if (!payload.type) return false
  1021. if ('success' === payload.type || 'info' === payload.type) {
  1022. if (payload.body && payload.body.isObjectActive && payload.body.isObjectActive > 0) {
  1023. n.parentNode.replaceChild(document.createTextNode('Active'), n)
  1024. } else {
  1025. console.log('TODO: activateObjectAjax unknown response', payload);
  1026. }
  1027. }
  1028. ");
  1029. if ('sort' === $sortByCol) {
  1030. echo UI::h('script', [], "
  1031. jQuery(document).ready(function (){
  1032. var tblNode$ = jQuery('#struct_table > tbody')
  1033. var getOrder = function () {
  1034. var orderIds = []
  1035. jQuery('#struct_table > tbody').children('.ta-sortable-item').each(function (idx, trNode) {
  1036. orderIds.push(jQuery(trNode).data('id_zasob'))
  1037. })
  1038. return orderIds
  1039. }
  1040. var sortOrder = getOrder()
  1041. console.log('sortOrder - init', sortOrder)
  1042. tblNode$.sortable({
  1043. axis: 'y',
  1044. handle: '.ta-sortable-item-handle',
  1045. items: '.ta-sortable-item',
  1046. update: function (event, ui) {
  1047. sortOrder = getOrder()
  1048. tblNode$.sortable('disable')
  1049. tblNode$.find('.ta-sortable-item-handle').css({color:'silver'})
  1050. console.log('TODO: disable sortable while ajax')
  1051. // window.setTimeout(function () {
  1052. // tblNode$.find('.ta-sortable-item-handle').css({color:'black'})
  1053. // console.log('TODO: ajax fetch result')
  1054. // tblNode$.sortable('enable')
  1055. // tblNode$.sortable('cancel')
  1056. // }, 1000)
  1057. window.fetch(
  1058. URI(window.location.href)
  1059. .setSearch('_task', 'updateAntAclSortAjax')
  1060. .setSearch('idZasobOrder', sortOrder)
  1061. .build().toString(),
  1062. {
  1063. method: 'POST',
  1064. headers: {
  1065. 'Content-Type': 'application/x-www-form-urlencoded' // query string
  1066. },
  1067. credentials: 'same-origin',
  1068. body: JSON.stringify({
  1069. namespace: URI.parseQuery(window.location.search).namespace,
  1070. sortBy: '{$sortByCol}',
  1071. sortByDir: '{$sortByDir}',
  1072. sortOrder: sortOrder,
  1073. })
  1074. }
  1075. ).then(function(response) {
  1076. return response.json()
  1077. }).then(function(payload) {
  1078. console.log('updateAntAclSortAjax response', payload);
  1079. tblNode$.sortable('enable')
  1080. if ('success' !== payload.type) {
  1081. tblNode$.sortable('cancel')
  1082. }
  1083. tblNode$.sortable('enable')
  1084. tblNode$.find('.ta-sortable-item-handle').css({color:'black'})
  1085. p5UI__notifyAjaxCallback({
  1086. type: payload.type || 'error',
  1087. msg: payload.msg || 'Request error'
  1088. });
  1089. if ('success' === payload.type) {
  1090. window.location.reload(true)
  1091. }
  1092. }).catch(function(e) {
  1093. tblNode$.sortable('enable')
  1094. tblNode$.sortable('cancel')
  1095. tblNode$.find('.ta-sortable-item-handle').css({color:'black'})
  1096. p5UI__notifyAjaxCallback({
  1097. type: 'error',
  1098. msg: 'Request error ' + e
  1099. });
  1100. })
  1101. }
  1102. });
  1103. });
  1104. ");
  1105. }
  1106. if ($item['isObjectActive']) {
  1107. echo UI::hButtonAjax("Dodaj podstawowy proces dla obiektu '{$item['namespace']}' - read only (TODO)", 'addObjectBaseProcesAjax', [
  1108. 'class' => "btn btn-xs btn-default",
  1109. 'href' => Router::getRoute('Storage')->getLink('addObjectBaseProcesAjax'),
  1110. 'data' => [ 'namespace' => $item['namespace'] ]
  1111. ]);
  1112. UI::hButtonAjaxOnResponse('addObjectBaseProcesAjax', /* payload, n */ "
  1113. jQuery.notify(payload.msg, payload.type)
  1114. ");
  1115. }
  1116. DBG::nicePrint($item, '$item');
  1117. }
  1118. public function updateAntAclSortAjaxAction() {
  1119. return Response::sendTryCatchJson(array($this, 'updateAntAclSortAjax'), $args = 'JSON_FROM_REQUEST_BODY');
  1120. }
  1121. public function updateAntAclSortAjax($args) {
  1122. DBG::log($args, 'array', "args");
  1123. $namespace = V::get('namespace', '', $args);
  1124. if (empty($namespace)) throw new Exception("Missing param namespace");
  1125. $item = SchemaFactory::loadDefaultObject('SystemObject')->getItem($namespace, [ 'propertyName' => '*,field' ]);
  1126. DBG::log($item, 'array', "\$item");
  1127. $sortByArgName = 'sortBy';
  1128. $sortByCol = V::get($sortByArgName, 'namespace', $args);
  1129. $sortByDir = V::get("{$sortByArgName}Dir", 'asc', $args);
  1130. if ('sort' !== $sortByCol) throw new Exception("Only sort by SORT_PRIO allowed to update");
  1131. if (!in_array($sortByDir, ['asc', 'desc'])) throw new Exception("Wrong order by dir arg");
  1132. if ('asc' !== $sortByDir) throw new Exception("Only sort asc is allowed"); // DBG
  1133. $sortPrioIdsFromZasoby = DB::getPDO()->fetchAll("
  1134. select z.ID, z.SORT_PRIO
  1135. from CRM_LISTA_ZASOBOW z
  1136. where z.PARENT_ID = :p_id
  1137. order by z.SORT_PRIO asc, z.ID asc -- default order in Zasoby tree
  1138. ", [
  1139. ':p_id' => $item['idZasob']
  1140. ]);
  1141. DBG::log($sortPrioIdsFromZasoby, 'array', "\$sortPrioIdsFromZasoby");
  1142. $idZasobCurrentOrder = array_map(function ($orderRow) {
  1143. return (int)$orderRow['ID'];
  1144. }, $sortPrioIdsFromZasoby);
  1145. DBG::log($idZasobCurrentOrder, 'array', "\$idZasobCurrentOrder");
  1146. DBG::log(array_diff_assoc($args['sortOrder'], $idZasobCurrentOrder), 'array', "array_diff_assoc(\$args['sortOrder'], \$idZasobCurrentOrder)");
  1147. DBG::log(array_diff_assoc($idZasobCurrentOrder, $args['sortOrder']), 'array', "array_diff_assoc(\$idZasobCurrentOrder, \$args['sortOrder'])");
  1148. $orderDiff = array_diff_assoc($args['sortOrder'], $idZasobCurrentOrder);
  1149. foreach ($orderDiff as $sortPrio => $idZasob) {
  1150. DB::getPDO()->update('CRM_LISTA_ZASOBOW', 'ID', $idZasob, [
  1151. 'SORT_PRIO' => $sortPrio,
  1152. ]);
  1153. }
  1154. return [
  1155. 'type' => 'success',
  1156. 'msg' => "OK",
  1157. 'DBG__args' => $args
  1158. ];
  1159. }
  1160. public function removeFieldFromTrashAjaxAction() {
  1161. DBG::log($_REQUEST, 'array', '$_REQUEST');
  1162. Response::sendTryCatchJson(array($this, 'removeFieldFromTrashAjax'), $_REQUEST);
  1163. }
  1164. public function removeFieldFromTrashAjax($args) {
  1165. $namespace = V::get('namespace', '', $args);
  1166. if (empty($namespace)) throw new HttpException("Missing namespace");
  1167. $fieldNamespace = V::get('fieldNamespace', '', $args);
  1168. if (empty($fieldNamespace)) throw new HttpException("Missing fieldNamespace");
  1169. $fieldItem = SchemaFactory::loadDefaultObject('SystemObjectField')->getItem($fieldNamespace);
  1170. if (!$fieldItem) throw new HttpException("Field not found '{$fieldNamespace}'", 404);
  1171. DBG::log($fieldItem, 'array', "\$fieldItem");
  1172. if ('p5:enum' === $fieldItem['xsdType']) {
  1173. // DBG::log(DB::getPDO()->fetchAll("
  1174. // select e.*
  1175. // from `CRM_#CACHE_ACL_OBJECT_FIELD_enum` e
  1176. // where e.objectNamespace = :objectNamespace
  1177. // and e.fieldNamespace = :fieldNamespace
  1178. // ", [
  1179. // ':objectNamespace' => $fieldItem['objectNamespace'],
  1180. // ':fieldNamespace' => $fieldItem['fieldNamespace'],
  1181. // ]), 'array', "enum values");
  1182. DB::getPDO()->execSql("
  1183. DELETE from `CRM_#CACHE_ACL_OBJECT_FIELD_enum`
  1184. where objectNamespace = :objectNamespace
  1185. and fieldNamespace = :fieldNamespace
  1186. and isActive = 0
  1187. ", [
  1188. ':objectNamespace' => $fieldItem['objectNamespace'],
  1189. ':fieldNamespace' => $fieldItem['fieldNamespace'],
  1190. ]);
  1191. }
  1192. DB::getPDO()->execSql("
  1193. DELETE from `CRM_#CACHE_ACL_OBJECT_FIELD`
  1194. where namespace = :namespace
  1195. and objectNamespace = :objectNamespace
  1196. and _rootTableName = :rootTableName
  1197. and isActive = 0
  1198. limit 1
  1199. ", [
  1200. 'namespace' => $fieldItem['namespace'],
  1201. 'objectNamespace' => $fieldItem['objectNamespace'],
  1202. 'rootTableName' => $fieldItem['_rootTableName'],
  1203. ]);
  1204. if ($fieldItem['idZasob'] > 0) {
  1205. $zasob = DB::getPDO()->fetchFirst(" select z.ID, z.A_STATUS, z.DESC from CRM_LISTA_ZASOBOW z where z.ID = :id ", [ ':id' => $fieldItem['idZasob'] ]);
  1206. if ($zasob) {
  1207. if ('DELETED' !== $zasob['A_STATUS']) {
  1208. $affected = DB::getPDO()->update('CRM_LISTA_ZASOBOW', 'ID', $zasob['ID'], [
  1209. 'A_STATUS' => 'DELETED',
  1210. 'A_RECORD_UPDATE_DATE' => 'NOW()',
  1211. 'A_RECORD_UPDATE_AUTHOR' => User::getLogin(),
  1212. ]);
  1213. if ($affected) {
  1214. DB::getPDO()->insert('CRM_LISTA_ZASOBOW_HIST', [
  1215. 'ID_USERS2' => $zasob['ID'],
  1216. 'A_STATUS' => 'DELETED',
  1217. 'A_RECORD_CREATE_DATE' => 'NOW()',
  1218. 'A_RECORD_CREATE_AUTHOR' => User::getLogin(),
  1219. ]);
  1220. }
  1221. }
  1222. }
  1223. $wskazniki = DB::getPDO()->fetchAll("
  1224. select w.ID, w.A_STATUS
  1225. from CRM_WSKAZNIK w
  1226. where w.ID_ZASOB = :id
  1227. ", [ ':id' => $fieldItem['idZasob'] ]);
  1228. if (!empty($wskazniki)) {
  1229. foreach ($wskazniki as $wsk) {
  1230. if ('DELETED' !== $wsk['A_STATUS']) {
  1231. $affected = DB::getPDO()->update('CRM_WSKAZNIK', 'ID', $wsk['ID'], [
  1232. 'A_STATUS' => 'DELETED',
  1233. 'A_RECORD_UPDATE_DATE' => 'NOW()',
  1234. 'A_RECORD_UPDATE_AUTHOR' => User::getLogin(),
  1235. ]);
  1236. if ($affected) {
  1237. DB::getPDO()->insert('CRM_WSKAZNIK_HIST', [
  1238. 'ID_USERS2' => $wsk['ID'],
  1239. 'A_STATUS' => 'DELETED',
  1240. 'A_RECORD_CREATE_DATE' => 'NOW()',
  1241. 'A_RECORD_CREATE_AUTHOR' => User::getLogin(),
  1242. ]);
  1243. }
  1244. }
  1245. }
  1246. }
  1247. }
  1248. return [
  1249. 'type' => "success",
  1250. 'msg' => "Usunięto pole {$fieldItem['fieldNamespace']}",
  1251. ];
  1252. }
  1253. public function addFieldToZasobyAjaxAction() {
  1254. DBG::log($_REQUEST, 'array', '$_REQUEST');
  1255. Response::sendTryCatchJson(array($this, 'addFieldToZasobyAjax'), $_REQUEST);
  1256. }
  1257. public function addFieldToZasobyAjax($args) {
  1258. $namespace = V::get('namespace', '', $args);
  1259. if (empty($namespace)) throw new HttpException("Missing namespace");
  1260. $fieldNamespace = V::get('fieldNamespace', '', $args);
  1261. if (empty($fieldNamespace)) throw new HttpException("Missing fieldNamespace");
  1262. $fieldItem = SchemaFactory::loadDefaultObject('SystemObjectField')->getItem($fieldNamespace);
  1263. if (!$fieldItem) throw new HttpException("Field not found '{$fieldNamespace}'", 404);
  1264. DBG::log($fieldItem, 'array', "\$fieldItem");
  1265. if ($fieldItem['idZasob'] > 0) throw (new AlertSuccessException("Field already added to Zasoby '{$fieldItem['idZasob']}'"))->setBody([ 'id' => $fieldItem['idZasob'] ]);
  1266. $objectItem = SchemaFactory::loadDefaultObject('SystemObject')->getItem($namespace);
  1267. if (!$objectItem) throw new HttpException("Object not found '{$namespace}'", 404);
  1268. DBG::log($objectItem, 'array', "\$objectItem");
  1269. if (!$objectItem['idZasob']) throw new Exception("Missing Object idZasob");
  1270. $zasobItem = DB::getPDO()->fetchFirst("
  1271. select zField.ID, zField.`DESC`, zField.`TYPE`, zField.PARENT_ID
  1272. from CRM_LISTA_ZASOBOW as zField
  1273. join CRM_LISTA_ZASOBOW as zTable on(zTable.ID = zField.PARENT_ID)
  1274. where zTable.`ID` = '{$objectItem['idZasob']}'
  1275. and zTable.`TYPE` = 'TABELA'
  1276. and zField.`DESC` = '{$fieldItem['fieldNamespace']}'
  1277. and zField.`TYPE` = 'KOMORKA'
  1278. ");
  1279. if ($zasobItem) {
  1280. SchemaFactory::loadDefaultObject('SystemObjectField')->updateItem([
  1281. 'namespace' => $fieldItem['namespace'],
  1282. 'idZasob' => $zasobItem['ID']
  1283. ]);
  1284. throw (new AlertSuccessException("Zasob już istnieje"))->setBody([ 'id' => $zasobItem['ID'] ]);
  1285. }
  1286. $newFieldItem = [
  1287. 'PARENT_ID' => $objectItem['idZasob'],
  1288. 'TYPE' => 'KOMORKA',
  1289. 'DESC' => $fieldItem['fieldNamespace'],
  1290. 'DESC_PL' => $fieldItem['fieldNamespace'],
  1291. ];
  1292. DBG::log($newFieldItem, 'array', "add new field item");
  1293. try {
  1294. $acl = User::getAcl()->getObjectAcl('default_db', 'crm_lista_zasobow');
  1295. } catch (Exception $e) {
  1296. throw new Exception("Brak dostępu do tabeli Zasoby");
  1297. }
  1298. $createdId = $acl->addItem($newFieldItem);
  1299. if (!$createdId) throw new Exception("Nie udało się utworzyć nowego rekordu!");
  1300. SchemaFactory::loadDefaultObject('SystemObjectField')->updateItem([
  1301. 'namespace' => $fieldItem['namespace'],
  1302. 'idZasob' => $createdId
  1303. ]);
  1304. throw (new AlertSuccessException("Utworzono pomyślnie rekord nr {$createdId}"))->setBody([ 'id' => $createdId ]);
  1305. }
  1306. }