Storage.php 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854
  1. <?php
  2. // @requires $_SERVER['SERVER_NAME']
  3. Lib::loadClass('RouteBase');
  4. Lib::loadClass('Schema_TableFactory');
  5. Lib::loadClass('Response');
  6. Lib::loadClass('UI');
  7. /*
  8. # Storage:
  9. - [ ] view available storage (from Zasoby - type 'BAZA_DANYCH', 'DATABASE_MYSQL', ...)
  10. - [ ] check config for connection
  11. - [ ] add cells to Zasoby
  12. - [ ] create cells in Storage
  13. - [x] use PDO
  14. */
  15. class Route_Storage extends RouteBase {
  16. public function handleAuth() {
  17. if (!User::logged()) {
  18. User::authByRequest();
  19. }
  20. }
  21. public function defaultAction() {
  22. UI::gora();
  23. UI::menu();
  24. $this->navView();
  25. try {
  26. $storageList = $this->getStorageList();
  27. if (empty($storageList)) throw new Exception("No storage defined");
  28. $storageMenu = array();
  29. foreach ($storageList as $storage) {
  30. $menuItem = array();
  31. $menuItem['id'] = $id = $storage['ID'];
  32. $menuItem['nazwa'] = $storage['DESC'];
  33. $menuItem['typ'] = $storage['TYPE'];
  34. $menuItem['tabele i widoki'] = '<a href="index.php?_route=Storage&_task=tableList&idStorage=' . $id . '">' . "tabele" . '</a>';
  35. //$menuItem['views'] = '<a href="index.php?_route=Storage&_task=viewList&idStorage=' . $id . '">' . "views" . '</a>';
  36. $menuItem['raw info'] = '<a href="index.php?_route=Storage&_task=rawInfo&idStorage=' . $id . '">' . "raw info" . '</a>';
  37. $menuItem['xsd'] = '<a href="index.php?_route=Storage&_task=xsd&idStorage=' . $id . '" target="_blank">' . "xsd" . '</a>';
  38. $storageMenu[] = $menuItem;
  39. }
  40. {// core object list
  41. $menuItem = array();
  42. //$menuItem['id'] = 'Obiekty';
  43. $menuItem['nazwa'] = 'Obiekty podstawowe';
  44. $menuItem['typ'] = 'OBJECTS';
  45. $menuItem['tabele i widoki'] = '<a href="index.php?_route=Storage&_task=coreObjectList">' . "obiekty" . '</a>';
  46. //$menuItem['views'] = '<a href="index.php?_route=Storage&_task=viewList&idStorage=' . $id . '">' . "views" . '</a>';
  47. //$menuItem['raw info'] = '<a href="index.php?_route=Storage&_task=objectRawInfo">' . "raw info" . '</a>';
  48. // TODO: $menuItem['xsd'] = '<a href="index.php?_route=Storage&_task=xsd&idStorage=' . $id . '" target="_blank">' . "xsd" . '</a>';
  49. $storageMenu[] = $menuItem;
  50. }
  51. {// object list - for current company
  52. $hostName = $_SERVER['SERVER_NAME'];
  53. $cleanHostName = str_replace(array(".", "-"), '_', $hostName);
  54. $menuItem = array();
  55. //$menuItem['id'] = 'Obiekty';
  56. $menuItem['nazwa'] = "Obiekty dla domeny '{$cleanHostName}'";
  57. $menuItem['typ'] = 'OBJECTS';
  58. $menuItem['tabele i widoki'] = '<a href="index.php?_route=Storage&_task=objectList">' . "obiekty" . '</a>';
  59. //$menuItem['views'] = '<a href="index.php?_route=Storage&_task=viewList&idStorage=' . $id . '">' . "views" . '</a>';
  60. //$menuItem['raw info'] = '<a href="index.php?_route=Storage&_task=objectRawInfo">' . "raw info" . '</a>';
  61. // TODO: $menuItem['xsd'] = '<a href="index.php?_route=Storage&_task=xsd&idStorage=' . $id . '" target="_blank">' . "xsd" . '</a>';
  62. $storageMenu[] = $menuItem;
  63. }
  64. DBG::table("storageMenu", $storageMenu, __CLASS__, __FUNCTION__, __LINE__);
  65. } catch (Exception $e) {
  66. UI::alert('danger', "Error #" . $e->getCode() . "|" . $e->getLine() . ": " . $e->getMessage());
  67. }
  68. UI::dol();
  69. }
  70. public function getCoreObjectFromFile($objectName) {
  71. if ('default_db/' === substr($objectName, 0, 11)) {
  72. return array('name' => substr($objectName, 11));
  73. }
  74. $filePath = APP_PATH_SCHEMA . "/gui/core/{$objectName}.json";
  75. if (!file_exists($filePath)) throw new Exception("File not exists", 404);
  76. $json = file_get_contents($filePath);
  77. DBG::_('DBG', '>1', "{$objectName} filePath", $filePath, __CLASS__, __FUNCTION__, __LINE__);
  78. DBG::_('DBG', '>1', "{$objectName} file content", $json, __CLASS__, __FUNCTION__, __LINE__);
  79. $json = @json_decode($json, $assoc = true);
  80. DBG::_('DBG', '>1', "{$objectName} json_last_error()", json_last_error(), __CLASS__, __FUNCTION__, __LINE__);
  81. if (null == $json && 0 !== json_last_error()) throw new Exception("Parse json error for object '{$objectName}': " . json_last_error());
  82. $jsonParent = array();
  83. $parent = (is_array($json['parent_object']))? end($json['parent_object']) : $json['parent_object'];
  84. $jsonParent = $this->getCoreObjectFromFile($parent);
  85. return array_merge_recursive($jsonParent, $json);
  86. }
  87. public function coreObjectStructAction() {
  88. UI::gora();
  89. UI::menu();
  90. $this->navView();
  91. try {
  92. $object = V::get('object', '', $_REQUEST, 'word');
  93. if (empty($object)) throw new Exception("Missing Object name");
  94. $json = $this->getCoreObjectFromFile($object);
  95. DBG::_(true, true, "json", $json, __CLASS__, __FUNCTION__, __LINE__);
  96. } catch (Exception $e) {
  97. UI::alert('danger', "Error #" . $e->getCode() . "|" . $e->getLine() . ": " . $e->getMessage());
  98. }
  99. UI::dol();
  100. }
  101. public function coreObjectListAction() {
  102. UI::gora();
  103. UI::menu();
  104. $this->navView();
  105. try {
  106. $files = glob(APP_PATH_SCHEMA . "/gui/core/*.json", GLOB_NOSORT);
  107. //DBG::_(true, true, "files", $files);
  108. $objectList = array();
  109. foreach ($files as $filePath) {
  110. $objItem = array();
  111. $fileName = basename($filePath);
  112. $objName = substr($fileName, 0, -5);// remove ext '.json'
  113. $objItem['name'] = $objName;
  114. $objItem['file_name'] = $fileName;
  115. $objItem['label'] = "";// TODO: read from json
  116. $objItem['struktura'] = '<a href="index.php?_route=Storage&_task=coreObjectStruct&object=' . $objName . '">' . "struct" . '</a>';
  117. $objectList[] = $objItem;
  118. }
  119. usort($objectList, function($rowA, $rowB) {
  120. $a = $rowA['nazwa']; $b = $rowB['nazwa'];
  121. if ($a == $b) return 0;
  122. return ($a < $b) ? -1 : 1;
  123. });
  124. DBG::table("objectList", $objectList, __CLASS__, __FUNCTION__, __LINE__);
  125. } catch (Exception $e) {
  126. UI::alert('danger', "Error #" . $e->getCode() . "|" . $e->getLine() . ": " . $e->getMessage());
  127. }
  128. UI::dol();
  129. }
  130. public function objectListAction() {
  131. UI::gora();
  132. UI::menu();
  133. try {
  134. } catch (Exception $e) {
  135. UI::alert('danger', "Error #" . $e->getCode() . "|" . $e->getLine() . ": " . $e->getMessage());
  136. }
  137. UI::dol();
  138. }
  139. public function tableListAction() {
  140. UI::gora();
  141. UI::menu();
  142. $this->navView();
  143. try {
  144. $idStorage = V::get('idStorage', 0, $_REQUEST, 'int');
  145. if (empty($idStorage)) throw new Exception("No id storage");
  146. $storageList = $this->getStorageList();
  147. if (empty($storageList)) throw new Exception("No storage defined");
  148. if (!array_key_exists($idStorage, $storageList)) throw new Exception("Storage id='{$idStorage}' not exists");
  149. $storagePdo = DB::getStorage($idStorage);
  150. $viewRealList = $storagePdo->getViewList();
  151. $tableRealList = $storagePdo->getTableList();
  152. $tableZasobList = array();
  153. foreach (DB::getPDO()->fetchAllByKey("
  154. select z.ID, z.`DESC`, z.A_STATUS
  155. from CRM_LISTA_ZASOBOW z
  156. where z.PARENT_ID = '{$idStorage}'
  157. ", $key = 'DESC') as $ind => $row) {
  158. $tableZasobList[strtolower($ind)] = $row;
  159. }
  160. $emptyItem = array();
  161. $emptyItem['nazwa'] = '';
  162. $emptyItem['type'] = '';
  163. $emptyItem['id_zasob'] = '';
  164. $emptyItem['struktura'] = '';
  165. $emptyItem['objectTest'] = '';
  166. $emptyItem['xsd'] = '';
  167. $emptyItem['isHist'] = '';
  168. $emptyItem['uwagi'] = '';
  169. $tableList = array();
  170. foreach ($tableRealList as $row) {
  171. $tblName = $row['table_name'];
  172. $tblItem = V::cloneArray($emptyItem);
  173. $tblItem['nazwa'] = $tblName;
  174. $tblItem['type'] = $row['table_type'];
  175. $tblItem['struktura'] = '<a href="index.php?_route=Storage&_task=tableStruct&idStorage=' . $idStorage . '&table=' . $tblName . '">' . "struct" . '</a>';
  176. $tblItem['xsd'] = '<a href="index.php?_route=Storage&_task=tableXsd&idStorage=' . $idStorage . '&table=' . $tblName . '" target="_blank">' . "xsd" . '</a>';
  177. $tblItem['objectTest'] = '<a href="index.php?_route=Storage&_task=objectTest&idStorage=' . $idStorage . '&table=' . $tblName . '">' . "objectTest" . '</a>';
  178. $tblItem['isHist'] = ('_hist' == substr($tblName, -5));
  179. $tblItem['uwagi'] = '';
  180. $tblZasob = V::get($tblName, '', $tableZasobList);
  181. if ($tblZasob) {
  182. $tableZasobList[$tblName]['_checked'] = true;
  183. $tblItem['id_zasob'] = $tblZasob['ID'];
  184. } else {
  185. $tblItem['uwagi'] .= 'TODO: ADD ZASOB';
  186. $ajaxAddZasobLink = Request::getUriDirName() . "/index.php?_route=Storage&_task=addTableToZasoby&idStorage={$idStorage}&tblName={$tblName}";
  187. $onClick = "return p5UI__ButtonAjax(this, 'p5UIBtnAjax:Storage:addToZasoby', { href: '{$ajaxAddZasobLink}' })";
  188. $tblItem['id_zasob'] = '<a onclick="'.$onClick.'" class="btn btn-xs btn-primary" href="#">TODO: ADD ZASOB</a>';
  189. }
  190. $tableList[] = $tblItem;
  191. }
  192. foreach ($viewRealList as $row) {
  193. $tblName = $row['table_name'];
  194. $tblItem = V::cloneArray($emptyItem);
  195. $tblItem['nazwa'] = $tblName;
  196. $tblItem['type'] = $row['table_type'];
  197. $tblItem['struktura'] = '<a href="index.php?_route=Storage&_task=viewStruct&idStorage=' . $idStorage . '&table=' . $tblName . '">' . "struct" . '</a>';
  198. $tblItem['uwagi'] = '';
  199. $tblZasob = V::get($tblName, '', $tableZasobList);
  200. if ($tblZasob) {
  201. $tableZasobList[$tblName]['_checked'] = true;
  202. $tblItem['id_zasob'] = $tblZasob['ID'];
  203. } else {
  204. $tblItem['uwagi'] .= 'TODO: ADD ZASOB';
  205. $tblItem['id_zasob'] = 'TODO: ADD ZASOB';
  206. }
  207. $tableList[] = $tblItem;
  208. }
  209. foreach ($tableZasobList as $tblName => $row) {
  210. if (!$row['_checked']) {
  211. $tblItem = V::cloneArray($emptyItem);
  212. $tblItem['nazwa'] = $tblName;
  213. $tblItem['id_zasob'] = $row['ID'];
  214. $tblItem['type'] = 'unknown';
  215. $tblItem['uwagi'] = 'TODO: nie istnieje w bazie danych';
  216. $tableList[] = $tblItem;
  217. }
  218. }
  219. usort($tableList, function($rowA, $rowB) {
  220. $a = $rowA['nazwa']; $b = $rowB['nazwa'];
  221. if ($a == $b) return 0;
  222. $a1 = substr($a, 0, 1); $b1 = substr($b, 0, 1);
  223. if (('_' == $a1 || '_' == $b1) && $a1 != $b1) {
  224. return ($a1 < $b1) ? 1 : -1;
  225. }
  226. return ($a < $b) ? -1 : 1;
  227. });
  228. DBG::table("tableList", $tableList, __CLASS__, __FUNCTION__, __LINE__);
  229. ?>
  230. <script>
  231. jQuery(document).on('p5UIBtnAjax:Storage:addToZasoby:click', function(e, n, payload) {
  232. console.log('event p5UIBtnAjax:Storage:addToZasoby:click', n, payload);
  233. });
  234. jQuery(document).on('p5UIBtnAjax:Storage:addToZasoby:ajaxLoaded', function(e, n, payload) {
  235. console.log('event p5UIBtnAjax:Storage:addToZasoby:ajaxLoaded', n, payload);
  236. if ('success' == payload.type && payload.body && payload.body.id > 0) {
  237. jQuery(n).parents('td').text(payload.body.id);
  238. }
  239. jQuery.notify(payload.msg, payload.type);
  240. });
  241. </script>
  242. <?php
  243. } catch (Exception $e) {
  244. UI::alert('danger', "Error #" . $e->getCode() . "|" . $e->getLine() . ": " . $e->getMessage());
  245. }
  246. UI::dol();
  247. }
  248. public function rawInfoAction() {
  249. UI::gora();
  250. UI::menu();
  251. $this->navView();
  252. try {
  253. $idStorage = V::get('idStorage', 0, $_REQUEST, 'int');
  254. if (empty($idStorage)) throw new Exception("No id storage");
  255. $storageList = $this->getStorageList();
  256. if (empty($storageList)) throw new Exception("No storage defined");
  257. if (!array_key_exists($idStorage, $storageList)) throw new Exception("No id storage not exists");
  258. $storagePdo = DB::getStorage($idStorage);
  259. $rawInfo = $storagePdo->getTableListWithInfo();
  260. DBG::table("rawInfo", $rawInfo, __CLASS__, __FUNCTION__, __LINE__);
  261. } catch (Exception $e) {
  262. UI::alert('danger', "Error #" . $e->getCode() . "|" . $e->getLine() . ": " . $e->getMessage());
  263. }
  264. UI::dol();
  265. }
  266. public function tableStructAction() {
  267. UI::gora();
  268. UI::menu();
  269. $this->navView();
  270. try {
  271. $idStorage = V::get('idStorage', 0, $_REQUEST, 'int');
  272. if (empty($idStorage)) throw new Exception("No id storage");
  273. $storageList = $this->getStorageList();
  274. if (empty($storageList)) throw new Exception("No storage defined");
  275. if (!array_key_exists($idStorage, $storageList)) throw new Exception("No id storage not exists");
  276. $tblName = V::get('table', '', $_REQUEST, 'word');
  277. if (empty($tblName)) throw new Exception("No table name");
  278. $storagePdo = DB::getStorage($idStorage);
  279. $tblStruct = $storagePdo->getTableStruct($tblName);
  280. $idTable = $this->fetchTableId($idStorage, $tblName);
  281. if ($idTable <= 0) {
  282. UI::alert('warning', "Zasob tabela '{$tblName}' nie istnieje");// TODO: add p5UI btn
  283. DBG::table("tblStruct", $tblStruct, __CLASS__, __FUNCTION__, __LINE__);
  284. throw new Exception("Zasob tabela '{$tblName}' nie istnieje");
  285. }
  286. $cellZasobList = array();
  287. foreach (DB::getPDO()->fetchAllByKey("
  288. select z.ID, z.`DESC`, z.A_STATUS
  289. from CRM_LISTA_ZASOBOW z
  290. where z.PARENT_ID = '{$idTable}'
  291. ", $key = 'DESC') as $ind => $row) {
  292. $cellZasobList[strtolower($ind)] = $row;
  293. }
  294. $emptyItem = array();
  295. $emptyItem['name'] = '';
  296. $emptyItem['id_zasob'] = '';
  297. $emptyItem['uwagi'] = '';
  298. $emptyItem['type'] = '';
  299. $emptyItem['is_nullable'] = '';
  300. $emptyItem['default_value'] = '';
  301. $emptyItem['default_is_null'] = '';
  302. $emptyItem['max_length'] = '';
  303. $emptyItem['num_precision'] = '';
  304. $emptyItem['num_scale'] = '';
  305. $emptyItem['char_encoding'] = '';
  306. $emptyItem['char_collation'] = '';
  307. $emptyItem['extra'] = '';
  308. $emptyItem['raw_storage_type'] = '';
  309. $tableList = array();
  310. foreach ($tblStruct as $row) {
  311. $cellName = $row['name'];
  312. $tblItem = V::cloneArray($emptyItem);
  313. $tblItem['name'] = $cellName;
  314. foreach ($row as $fldName => $fldVal) {
  315. if (array_key_exists($fldName, $tblItem)) $tblItem[$fldName] = $fldVal;
  316. }
  317. $tblItem['uwagi'] = '';
  318. $lowerCellName = strtolower($cellName);
  319. $tblZasob = V::get($lowerCellName, '', $cellZasobList);
  320. if ($tblZasob) {
  321. $cellZasobList[$lowerCellName]['_checked'] = true;
  322. $tblItem['id_zasob'] = $tblZasob['ID'];
  323. } else {
  324. $tblItem['uwagi'] .= '!Zasob';//'TODO: ADD ZASOB';
  325. $ajaxAddZasobLink = Request::getUriDirName() . "/index.php?_route=Storage&_task=addCellToZasoby&idStorage={$idStorage}&tblName={$tblName}&cellName={$cellName}";
  326. $onClick = "return p5UI__ButtonAjax(this, 'p5UIBtnAjax:Storage:addToZasoby', { href: '{$ajaxAddZasobLink}' })";
  327. $tblItem['id_zasob'] = '<a onclick="'.$onClick.'" class="btn btn-xs btn-primary" href="#">TODO: ADD ZASOB</a>';
  328. }
  329. $tableList[] = $tblItem;
  330. }
  331. foreach ($cellZasobList as $cellName => $row) {
  332. if (!$row['_checked']) {
  333. $tblItem = V::cloneArray($emptyItem);
  334. $tblItem['name'] = $cellName;
  335. $tblItem['id_zasob'] = $row['ID'];
  336. $tblItem['uwagi'] = '!DB';//'TODO: nie istnieje w bazie danych';
  337. $tableList[] = $tblItem;
  338. }
  339. }
  340. usort($tableList, function($rowA, $rowB) {
  341. $a = $rowA['name']; $b = $rowB['name'];
  342. if ('ID' == $a) return -1;
  343. if ('ID' == $b) return 1;
  344. if ($a == $b) return 0;
  345. $a1 = substr($a, 0, 1); $b1 = substr($b, 0, 1);
  346. if (('_' == $a1 || '_' == $b1) && $a1 != $b1) {
  347. return ($a1 < $b1) ? 1 : -1;
  348. }
  349. return ($a < $b) ? -1 : 1;
  350. });
  351. DBG::table("tableList", $tableList, __CLASS__, __FUNCTION__, __LINE__);
  352. ?>
  353. <script>
  354. jQuery(document).on('p5UIBtnAjax:Storage:addToZasoby:click', function(e, n, payload) {
  355. console.log('event p5UIBtnAjax:Storage:addToZasoby:click', n, payload);
  356. });
  357. jQuery(document).on('p5UIBtnAjax:Storage:addToZasoby:ajaxLoaded', function(e, n, payload) {
  358. console.log('event p5UIBtnAjax:Storage:addToZasoby:ajaxLoaded', n, payload);
  359. if ('success' == payload.type && payload.body && payload.body.id > 0) {
  360. jQuery(n).parents('td').next('td').text(payload.body.id);
  361. jQuery(n).remove();
  362. }
  363. jQuery.notify(payload.msg, payload.type);
  364. });
  365. </script>
  366. <?php
  367. } catch (Exception $e) {
  368. UI::alert('danger', "Error #" . $e->getCode() . "|" . $e->getLine() . ": " . $e->getMessage());
  369. }
  370. UI::dol();
  371. }
  372. public function xsdAction() {
  373. $idStorage = V::get('idStorage', 0, $_REQUEST, 'int');
  374. $storage = DB::getStorage($idStorage);
  375. $tableRealList = $storage->getTableList();
  376. $srvName = $_SERVER['SERVER_NAME'];
  377. $storageZasobId = $storage->getZasobId();
  378. $objNs = "p5_{$storageZasobId}_{$tblName}";
  379. $objNsUri = "https://biuro.biall-net.pl/api/{$storageZasobId}/{$tblName}";
  380. $p5TypePrefix = "p5Type";
  381. $p5TypeNsUri = "http://biuro.biall-net.pl/p5/schema/types";
  382. $p5TypeNsLocation = "http://biuro.biall-net.pl/p5/schema/types.xsd";
  383. header('Content-type: text/plain; charset=utf-8');// TODO: test
  384. //header('Content-type: application/xml; charset=utf-8');
  385. $xmlWriter = new XMLWriter();
  386. $xmlWriter->openUri('php://output');
  387. $xmlWriter->setIndent(true);
  388. if (!$xmlWriter) throw new HttpException("Error no XMLWriter", 404);
  389. $xmlWriter->startDocument('1.0', 'UTF-8');
  390. $xmlWriter->startElement('xs:schema');
  391. $xmlWriter->writeAttribute('xmlns:xs', 'http://www.w3.org/2001/XMLSchema');
  392. $xmlWriter->writeAttribute('xmlns:vc', 'http://www.w3.org/2007/XMLSchema-versioning');
  393. $xmlWriter->writeAttribute("xmlns:{$p5TypePrefix}", $p5TypeNsUri);
  394. $xmlWriter->writeAttribute('elementFormDefault', 'qualified');
  395. $xmlWriter->writeAttribute('targetNamespace', $objNsUri);
  396. $xmlWriter->writeAttribute('vc:minVersion', '1.1');
  397. $xmlWriter->startElement('xs:import');
  398. $xmlWriter->writeAttribute('namespace', $p5TypeNsUri);
  399. $xmlWriter->writeAttribute('schemaLocation', $p5TypeNsLocation);
  400. $xmlWriter->endElement();// xs:import
  401. foreach ($tableRealList as $tbl) {
  402. $tblName = $tbl['table_name'];
  403. $this->tableXsdViewXmlWriter($xmlWriter, $idStorage, $tblName);
  404. }
  405. $xmlWriter->endElement();// xs:schema
  406. $xmlWriter->endDocument();
  407. }
  408. public function tableXsdAction() {
  409. $idStorage = V::get('idStorage', '', $_GET);
  410. $tblName = V::get('table', '', $_GET, 'word');
  411. if (empty($tblName)) die("Wrong table name");
  412. header('Content-type: text/plain; charset=utf-8');// TODO: test
  413. $storage = DB::getStorage($idStorage);
  414. $storageZasobId = $storage->getZasobId();
  415. $objNs = "p5_{$storageZasobId}_{$tblName}";
  416. $objNsUri = "https://biuro.biall-net.pl/api/{$storageZasobId}/{$tblName}";
  417. $p5TypePrefix = "p5Type";
  418. $p5TypeNsUri = "http://biuro.biall-net.pl/p5/schema/types";
  419. $p5TypeNsLocation = "http://biuro.biall-net.pl/p5/schema/types.xsd";
  420. //header('Content-type: application/xml; charset=utf-8');
  421. $xmlWriter = new XMLWriter();
  422. $xmlWriter->openUri('php://output');
  423. $xmlWriter->setIndent(true);
  424. if (!$xmlWriter) throw new HttpException("Error no XMLWriter", 404);
  425. $xmlWriter->startDocument('1.0', 'UTF-8');
  426. $xmlWriter->startElement('xs:schema');
  427. $xmlWriter->writeAttribute('xmlns:xs', 'http://www.w3.org/2001/XMLSchema');
  428. $xmlWriter->writeAttribute('xmlns:vc', 'http://www.w3.org/2007/XMLSchema-versioning');
  429. $xmlWriter->writeAttribute("xmlns:{$p5TypePrefix}", $p5TypeNsUri);
  430. $xmlWriter->writeAttribute('elementFormDefault', 'qualified');
  431. $xmlWriter->writeAttribute('targetNamespace', $objNsUri);
  432. $xmlWriter->writeAttribute('vc:minVersion', '1.1');
  433. $xmlWriter->startElement('xs:import');
  434. $xmlWriter->writeAttribute('namespace', $p5TypeNsUri);
  435. $xmlWriter->writeAttribute('schemaLocation', $p5TypeNsLocation);
  436. $xmlWriter->endElement();// xs:import
  437. $this->tableXsdViewXmlWriter($xmlWriter, $idStorage, $tblName);
  438. $xmlWriter->endElement();// xs:schema
  439. $xmlWriter->endDocument();
  440. }
  441. public function tableXsdViewXmlWriter(&$xmlWriter, $idStorage, $tblName) {
  442. $storage = DB::getStorage($idStorage);
  443. $schema = Schema_TableFactory::build($tblName, $idStorage, $_SERVER['SERVER_NAME']);
  444. $struct = $schema->getStruct();
  445. DBG::_('DBG', '>1', "struct", $struct, __CLASS__, __FUNCTION__, __LINE__);
  446. $typeName = "{$tblName}Type";
  447. $xmlWriter->startElement('xs:complexType');
  448. $xmlWriter->writeAttribute('name', $typeName);
  449. $xmlWriter->startElement('xs:sequence');
  450. foreach ($struct as $field) {
  451. $xmlWriter->startElement('xs:element');
  452. $xmlWriter->writeAttribute('name', $field['name']);
  453. $xmlWriter->writeAttribute('minOccurs', 0);// TODO: set minOccurs by default, etc.
  454. if ($field['is_nullable']) $xmlWriter->writeAttribute('nillable', 'true');
  455. if (null !== $field['default_value']) {
  456. $xmlWriter->writeAttribute('default', $field['default_value']);
  457. } else if (null === $field['default_value'] && $field['is_nullable']) {
  458. $xmlWriter->writeAttribute('default', $field['default_value']);
  459. } else {
  460. // TODO: Schema BUG?
  461. }
  462. if (empty($field['p5_restrictions'])) {
  463. $xmlWriter->writeAttribute('type', "p5Type:{$field['p5_type']}");
  464. } else {
  465. $xmlWriter->startElement('xs:simpleType');
  466. $xmlWriter->writeAttribute('base', "p5Type:{$field['p5_type']}");
  467. $xmlWriter->startElement('xs:restriction');
  468. if (!empty($field['p5_restrictions']['enumeration'])) {
  469. foreach ($field['p5_restrictions']['enumeration'] as $enumValue) {
  470. $xmlWriter->startElement('xs:enumeration');
  471. $xmlWriter->writeAttribute('value', $enumValue);
  472. $xmlWriter->endElement();// xs:enumeration
  473. }
  474. } else {
  475. // TODO: another restrictions...
  476. }
  477. $xmlWriter->endElement();// xs:restriction
  478. $xmlWriter->endElement();// xs:simpleType
  479. }
  480. $xmlWriter->endElement();// xs:element
  481. }
  482. $xmlWriter->endElement();// xs:sequence
  483. $xmlWriter->endElement();// xs:complexType
  484. return;
  485. // <xs:element maxOccurs="1" minOccurs="0" name="{$fldName}" nillable="true" type="xs:integer"/>
  486. $pKeyField = 'ID';//$storageObject->getPrimaryKeyFieldName();
  487. //DBG::_(true, true, "struct", $struct, __CLASS__, __FUNCTION__, __LINE__);
  488. foreach ($struct as $field) {
  489. $fldName = $vField->getName();
  490. $fldType = $vField->getType();
  491. $xsdType = $fldType->getTypeForXsd();
  492. if ($fldType->hasDefault()) {
  493. $fldDefault = $fldType->getDefault();
  494. if (!empty($fldDefault) || '0' === $fldDefault) {
  495. $elNode->setAttribute('default', $fldDefault);
  496. }
  497. }
  498. $fldRestrictions = $fldType->getRestrictions();
  499. if (empty($fldRestrictions)) {
  500. $elNode->setAttribute('type', "{$p5TypePrefix}:{$xsdType}");
  501. } else {
  502. $sType = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xs:simpleType');
  503. $elNode->appendChild($sType);
  504. $sTypeRes = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xs:restriction');
  505. $sType->appendChild($sTypeRes);
  506. $sTypeRes->setAttribute('base', "{$p5TypePrefix}:{$xsdType}");
  507. $enumList = $fldType->getEnumeration();
  508. if (empty($enumList)) {
  509. foreach ($fldRestrictions as $restricionName => $restrictionValue) {
  510. if ('maxLength' == $restricionName) {
  511. $sTypeResMaxLength = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xs:maxLength');
  512. $sTypeRes->appendChild($sTypeResMaxLength);
  513. $sTypeResMaxLength->setAttribute('value', $restrictionValue);
  514. } else if ('minLength' == $restricionName) {
  515. $sTypeResMinLength = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xs:minLength');
  516. $sTypeRes->appendChild($sTypeResMinLength);
  517. $sTypeResMinLength->setAttribute('value', $restrictionValue);
  518. } else if ('pattern' == $restricionName) {
  519. $sTypeResPattern = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xs:pattern');
  520. $sTypeRes->appendChild($sTypeResPattern);
  521. $sTypeResPattern->setAttribute('value', $restrictionValue);
  522. } else if ('fractionDigits' == $restricionName) {
  523. $sTypeResFractionDigits = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xs:fractionDigits');
  524. $sTypeRes->appendChild($sTypeResFractionDigits);
  525. $sTypeResFractionDigits->setAttribute('value', $restrictionValue);
  526. } else if ('totalDigits' == $restricionName) {
  527. $sTypeResTotalDigits = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xs:totalDigits');
  528. $sTypeRes->appendChild($sTypeResTotalDigits);
  529. $sTypeResTotalDigits->setAttribute('value', $restrictionValue);
  530. } else if ('maxExclusive' == $restricionName) {
  531. $sTypeResMaxExclusive = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xs:maxExclusive');
  532. $sTypeRes->appendChild($sTypeResMaxExclusive);
  533. $sTypeResMaxExclusive->setAttribute('value', $restrictionValue);
  534. } else if ('minExclusive' == $restricionName) {
  535. $sTypeResMinExclusive = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xs:minExclusive');
  536. $sTypeRes->appendChild($sTypeResMinExclusive);
  537. $sTypeResMinExclusive->setAttribute('value', $restrictionValue);
  538. } else if ('maxInclusive' == $restricionName) {
  539. $sTypeResMaxInclusive = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xs:maxInclusive');
  540. $sTypeRes->appendChild($sTypeResMaxInclusive);
  541. $sTypeResMaxInclusive->setAttribute('value', $restrictionValue);
  542. } else if ('minInclusive' == $restricionName) {
  543. $sTypeResMinInclusive = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xs:minInclusive');
  544. $sTypeRes->appendChild($sTypeResMinInclusive);
  545. $sTypeResMinInclusive->setAttribute('value', $restrictionValue);
  546. }
  547. /* TODO: xsd restrictions:
  548. enumeration Defines a list of acceptable values
  549. fractionDigits Specifies the maximum number of decimal places allowed. Must be equal to or greater than zero
  550. length Specifies the exact number of characters or list items allowed. Must be equal to or greater than zero
  551. maxExclusive Specifies the upper bounds for numeric values (the value must be less than this value)
  552. maxInclusive Specifies the upper bounds for numeric values (the value must be less than or equal to this value)
  553. maxLength Specifies the maximum number of characters or list items allowed. Must be equal to or greater than zero
  554. minExclusive Specifies the lower bounds for numeric values (the value must be greater than this value)
  555. minInclusive Specifies the lower bounds for numeric values (the value must be greater than or equal to this value)
  556. minLength Specifies the minimum number of characters or list items allowed. Must be equal to or greater than zero
  557. pattern Defines the exact sequence of characters that are acceptable
  558. totalDigits Specifies the exact number of digits allowed. Must be greater than zero
  559. whiteSpace Specifies how white space (line feeds, tabs, spaces, and carriage returns) is handled
  560. */
  561. }
  562. } else {
  563. foreach ($enumList as $enumValue) {
  564. $sTypeResEnum = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xs:enumeration');
  565. $sTypeRes->appendChild($sTypeResEnum);
  566. $sTypeResEnum->setAttribute('value', $enumValue);
  567. }
  568. }
  569. }
  570. }
  571. $elNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xs:element');
  572. $rootNode->appendChild($elNode);
  573. $elNode->setAttribute('name', $tblName);
  574. $elNode->setAttribute('type', "{$objNs}:{$typeName}");
  575. header('Content-type: application/xml');
  576. echo $dom->saveXML();
  577. exit;
  578. }
  579. public function navView() {
  580. $backLabel = 'back';
  581. $backLink = 'index.php?_route=Storage';
  582. $backDisabled = true;
  583. $currentLabel = 'Storage';
  584. $currentLink = 'index.php?_route=Storage';
  585. if ($task = V::get('_task', '', $_REQUEST)) {
  586. $currentLink = "index.php?_route=Storage&_task={$task}";
  587. $backDisabled = false;
  588. $idStorage = V::get('idStorage', 0, $_REQUEST, 'int');
  589. $tblName = V::get('table', '', $_REQUEST, 'word');
  590. $objName = V::get('object', '', $_REQUEST, 'word');
  591. switch ($task) {
  592. case 'tableList':
  593. case 'viewList':
  594. case 'rawInfo':
  595. $backLabel = 'Storage';
  596. $backLink = 'index.php?_route=Storage';
  597. $currentLink = "index.php?_route=Storage&_task={$task}&idStorage={$idStorage}";
  598. break;
  599. case 'tableStruct':
  600. $backLabel = "Tabele [{$idStorage}]";
  601. $backLink = "index.php?_route=Storage&_task=tableList&idStorage={$idStorage}";
  602. $currentLink = "index.php?_route=Storage&_task={$task}&idStorage={$idStorage}&table={$tblName}";
  603. break;
  604. case 'objectStruct': break;
  605. case 'coreObjectStruct':
  606. $backLabel = "Obiekty podstawowe";
  607. $backLink = "index.php?_route=Storage&_task=coreObjectList";
  608. $currentLink = "index.php?_route=Storage&_task={$task}&object={$objName}";
  609. break;
  610. }
  611. switch ($task) {
  612. case 'tableList': $currentLabel = "Tabele [{$idStorage}]"; break;
  613. case 'viewList': $currentLabel = "Widoki [{$idStorage}]"; break;
  614. case 'rawInfo': $currentLabel = "Raw info [{$idStorage}]"; break;
  615. case 'tableStruct': $currentLabel = "Struktura tabeli '{$tblName}'"; break;
  616. case 'coreObjectList': $currentLabel = "Obiekty podstawowe"; break;
  617. case 'coreObjectStruct': $currentLabel = "Obiekt '{$objName}'"; break;
  618. case 'objectList': $currentLabel = "Obiekty z aktualnej domeny"; break;// TODO: domain from $_GET
  619. }
  620. }
  621. ?>
  622. <nav class="navbar navbar-default navbar-static-top">
  623. <div class="container-fluid">
  624. <div class="navbar-left">
  625. <ul class="nav navbar-nav navbar-center">
  626. <li><a href="<?php echo $backLink; ?>" class="btn <?php echo ($backDisabled)? 'disabled' : ''; ?>"><i class="glyphicon glyphicon-chevron-left"></i> <?php echo $backLabel; ?></a></li>
  627. </ul>
  628. </div>
  629. <div class="navbar-left">
  630. <ul class="nav navbar-nav navbar-center">
  631. <li><a class="btn" href="<?php echo $currentLink; ?>"><?php echo $currentLabel; ?></a></li>
  632. </ul>
  633. </div>
  634. <div class="navbar-right">
  635. <!--
  636. <ul class="nav navbar-nav navbar-right">
  637. <li><a href="#">Link</a></li>
  638. <li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a>
  639. <ul class="dropdown-menu">
  640. <li><a href="#">Action</a></li>
  641. <li><a href="#">Another action</a></li>
  642. <li><a href="#">Something else here</a></li>
  643. <li role="separator" class="divider"></li>
  644. <li><a href="#">Separated link</a></li>
  645. </ul>
  646. </li>
  647. </ul>
  648. -->
  649. </div>
  650. </div>
  651. </nav>
  652. <?php
  653. }
  654. public function getStorageList() {
  655. $storageList = array();
  656. $sth = DB::getPDO()->prepare("
  657. select z.ID, z.`DESC`, z.`TYPE`
  658. from CRM_LISTA_ZASOBOW z
  659. where z.TYPE in('BAZA_DANYCH','DATABASE_MYSQL','DATABASE_POSTGRESQL')
  660. ");
  661. $sth->execute();
  662. $rows = $sth->fetchAll();
  663. foreach ($rows as $row) {
  664. $storageList[$row['ID']] = $row;
  665. }
  666. return $storageList;
  667. }
  668. public function addTableToZasobyAction() {// sends JSON
  669. $response = new stdClass();
  670. try {
  671. $response->id = 123; throw new AlertSuccessException("TEST: Utworzono pomyślnie rekord nr 123");
  672. $idStorage = V::get('storageId', '', $_GET);
  673. $tblName = V::get('tblName', '', $_GET, 'word');
  674. if (empty($tblName)) throw new HttpException("Wrong table name");
  675. // $response->zasobTblId = $zasobItemFound->TABLE_ID;
  676. // $response->zasobId = $zasobItemFound->ID;
  677. $storage = DB::getStorage($idStorage);
  678. $tableStruct = $storage->getTableStruct($tblName);
  679. $zasobStorageId = $storage->getZasobId();
  680. if (!is_numeric($zasobStorageId)) throw new HttpException("Storage id is not set in config file");
  681. $zasobItem = array();
  682. $zasobItem['PARENT_ID'] = $zasobStorageId;
  683. $zasobItem['TYPE'] = 'TABELA';
  684. $zasobItem['DESC'] = $tblName;
  685. $zasobItem['DESC_PL'] = $tblName;
  686. $zasobItemFound = null;
  687. {
  688. $rows = DB::getPDO()->fetchAll("
  689. select z.`ID`, z.`DESC`
  690. from `CRM_LISTA_ZASOBOW` z
  691. where z.`PARENT_ID`='{$zasobStorageId}'
  692. and z.`DESC`='{$tblName}'
  693. and z.`A_STATUS` in('NORMAL','WAITING')
  694. ");
  695. if (!empty($rows)) {
  696. $zasobItemFound = $rows[0]['ID'];
  697. }
  698. }
  699. if ($zasobItemFound > 0) {
  700. $response->_replaceButtonNode = "[{$zasobItemFound}]";
  701. throw new AlertInfoException("Zasob tabela '{$tblName}' już istnieje - nr '{$zasobItemFound}'");
  702. }
  703. $acl = User::getAcl()->getObjectAcl('default_db', 'crm_lista_zasobow');
  704. if (!$acl) throw new Exception("Brak dostępu do tabeli Zasoby");
  705. $item = array();
  706. $item['PARENT_ID'] = $zasobStorageId;
  707. $item['TYPE'] = 'TABELA';
  708. $item['DESC'] = $tblName;
  709. $item['DESC_PL'] = $tblName;
  710. if (DBG::isActive()) $response->_itemToCreate = $item;
  711. $createdId = $acl->addItem($item);
  712. if (!$createdId) throw new Exception("Nie udało się utworzyć nowego rekordu!");
  713. $response->id = $createdId;
  714. $response->record = $acl->getItem($createdId);
  715. $response->_replaceButtonNode = "[{$createdId}]";
  716. throw new AlertSuccessException("Utworzono pomyślnie rekord nr {$createdId}");
  717. } catch (AlertSuccessException $e) {
  718. $response->type = 'success';
  719. $response->msg = $e->getMessage();
  720. } catch (AlertInfoException $e) {
  721. $response->type = 'info';
  722. $response->msg = $e->getMessage();
  723. } catch (Exception $e) {
  724. $response->type = 'error';
  725. $response->msg = $e->getMessage();
  726. }
  727. Response::sendJsonExit($response);
  728. }
  729. public function addCellToZasobyAction() {// sends JSON
  730. $response = new stdClass();
  731. try {
  732. $response->id = 123; throw new AlertSuccessException("TEST: Utworzono pomyślnie rekord nr 123");
  733. $idStorage = V::get('storageId', '', $_GET);
  734. $tblName = V::get('tblName', '', $_GET, 'word');
  735. $cellName = V::get('cellName', '', $_GET, 'word');
  736. if (empty($tblName)) throw new HttpException("Wrong table name");
  737. if (empty($tblName)) throw new HttpException("Wrong cell name");
  738. $storage = DB::getStorage($idStorage);
  739. $tableStruct = $storage->getTableStruct($tblName);
  740. $zasobStorageId = $storage->getZasobId();
  741. if (!is_numeric($zasobStorageId)) throw new HttpException("Storage id is not set in config file");
  742. $idTable = $this->fetchTableId($zasobStorageId, $tblName);
  743. if ($idTable <= 0) throw new Exception("Zasob tabela '{$tblName}' nie istnieje");
  744. $acl = User::getAcl()->getObjectAcl('default_db', 'crm_lista_zasobow');
  745. if (!$acl) throw new Exception("Brak dostępu do tabeli Zasoby");
  746. $item = array();
  747. $item['PARENT_ID'] = $idTable;
  748. $item['TYPE'] = 'KOMORKA';
  749. $item['DESC'] = $cellName;
  750. $item['DESC_PL'] = $cellName;
  751. if (DBG::isActive()) $response->_itemToCreate = $item;
  752. $createdId = $acl->addItem($item);
  753. if (!$createdId) throw new Exception("Nie udało się utworzyć nowego rekordu!");
  754. $response->id = $createdId;
  755. $response->record = $acl->getItem($createdId);
  756. $response->_replaceButtonNode = "[{$createdId}]";
  757. throw new AlertSuccessException("Utworzono pomyślnie rekord nr {$createdId}");
  758. } catch (AlertSuccessException $e) {
  759. $response->type = 'success';
  760. $response->msg = $e->getMessage();
  761. } catch (AlertInfoException $e) {
  762. $response->type = 'info';
  763. $response->msg = $e->getMessage();
  764. } catch (Exception $e) {
  765. $response->type = 'error';
  766. $response->msg = $e->getMessage();
  767. }
  768. Response::sendJsonExit($response);
  769. }
  770. public function fetchTableId($idZasobStorage, $tblName) {
  771. $rows = DB::getPDO()->fetchAll("
  772. select z.`ID`, z.`DESC`
  773. from `CRM_LISTA_ZASOBOW` z
  774. where z.`PARENT_ID`='{$idZasobStorage}'
  775. and z.`DESC`='{$tblName}'
  776. and z.`A_STATUS` in('NORMAL','WAITING')
  777. ");
  778. if (!empty($rows)) return $rows[0]['ID'];
  779. return null;
  780. }
  781. }