Data_Source.php 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637
  1. <?php
  2. /**
  3. * API:
  4. * get($field_name) - source field value
  5. * get_item($id) - get item by ID
  6. */
  7. class Data_Source {
  8. var $_db;
  9. var $_tbl;// sql table name, TODO: or zasob ID
  10. var $_default_sql_limit;
  11. var $_fields_type;// array of fields ( name => type )
  12. var $_fields_perm;// array of field perm ( name => perm )
  13. var $_cols = array();
  14. var $_vCols = array();// setVirtualCols - TODO: use Typespecial
  15. var $_col_types = array();// TODO: array( col_name => TYPE )
  16. var $_sql_where;// sql where
  17. var $_sql_limit;
  18. var $_sql_offset;
  19. var $_sql_left_join;// TODO: left join in table
  20. var $_isAccessFltrAllowed = null;
  21. function __construct($db = null) {
  22. if ($db) {
  23. $this->_db = DB::getDB($db);
  24. } else {
  25. $this->_db = DB::getDB();
  26. }
  27. $this->_default_sql_limit = 10;
  28. }
  29. function set_table($tbl) {// TODO: RMME
  30. $this->setTable($tbl);
  31. }
  32. public function setTable($tbl) {
  33. $this->_tbl = $tbl;
  34. $this->_fields_type = array();
  35. $this->_fields_perm = array();
  36. }
  37. function get_cols() {
  38. // TODO: cache in session
  39. if (empty($this->_cols)) {
  40. if (!$this->_tbl) {
  41. return $this->_tbl;
  42. }
  43. $sql = "show fields from `{$this->_tbl}` ; ";
  44. $res = $this->_db->query($sql);
  45. while ($r = $this->_db->fetch($res)) {
  46. $this->_cols[$r->Field] = $r->Field;
  47. $this->_col_types[$r->Field] = $r->Type . ';' . $r->Default;
  48. }
  49. }
  50. return $this->_cols;
  51. }
  52. function set_cols($cols) {// TODO: RMME
  53. $this->setCols($cols);
  54. }
  55. function setCols($cols) {
  56. foreach ($cols as $v_field_name) {
  57. $this->_cols[$v_field_name] = $v_field_name;
  58. }
  59. }
  60. public function setColTypes($types) {
  61. $this->_col_types = $types;
  62. // TableAcl->getTypes(): $this->_types[$fieldName] = array('type'=>$h[1], 'null'=>('YES' == $h[2]), 'default'=>$h[4]);
  63. }
  64. public function getColDefault($fieldName) {
  65. if (array_key_exists($fieldName, $this->_types)) {
  66. if (!empty($this->_types[$fieldName]['default'])) {
  67. return $this->_types[$fieldName]['default'];
  68. }
  69. }
  70. return '';
  71. }
  72. function setVirtualCols($cols) {
  73. foreach ($cols as $v_field_name) {
  74. $this->_vCols[$v_field_name] = $v_field_name;
  75. }
  76. }
  77. public function setFieldGroupWrite($fieldName, $fieldExists = false) {
  78. if ($fieldExists) {
  79. $this->_fieldGroupWrite = $fieldName;
  80. $this->_cols[$fieldName] = $fieldName;
  81. }
  82. }
  83. public function setFieldGroupRead($fieldName, $fieldExists = false) {
  84. if ($fieldExists) {
  85. $this->_fieldGroupRead = $fieldName;
  86. $this->_cols[$fieldName] = $fieldName;
  87. }
  88. }
  89. function _get_sql_cols() {
  90. $sql_cols = "t.*";
  91. if (!empty($this->_cols)) {
  92. $sql_cols_arr = array();
  93. foreach ($this->_cols as $k_field => $v_field_label) {
  94. $sql_cols_arr []= "t.`{$k_field}`";
  95. }
  96. $sql_cols = implode(", ", $sql_cols_arr);
  97. }
  98. if(V::get('DBG_DS', 0, $_GET) > 0){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">sql_cols (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($sql_cols);echo'</pre>'."\n\n";}
  99. return $sql_cols;
  100. }
  101. public function setAccessFltrAllowed($isAccessFltrAllowed) {
  102. $this->_isAccessFltrAllowed = $isAccessFltrAllowed;
  103. }
  104. public function isAccessFltrAllowed() {
  105. if (false === $this->_isAccessFltrAllowed) {
  106. return false;
  107. }
  108. else if ( !empty($this->_fieldGroupWrite)
  109. && !empty($this->_fieldGroupRead)
  110. && array_key_exists('A_ADM_COMPANY', $this->_cols)
  111. && array_key_exists('A_CLASSIFIED', $this->_cols)
  112. ) {
  113. return true;
  114. }
  115. }
  116. function getSpecialFilters() {
  117. $fltrs = array();
  118. if (array_key_exists('A_PROBLEM', $this->_cols)) {
  119. $fltrs['Problemy'] = new stdClass();
  120. $fltrs['Problemy']->icon = 'icon-warning-sign';
  121. $fltrs['Problemy']->btns = array();
  122. $fltrs['Problemy']->btns['PROBLEMY'] = (object)array('value'=>'PROBLEM');
  123. $fltrs['Problemy']->btns['OSTRZEZENIA'] = (object)array('value'=>'WARNING');
  124. $fltrs['Problemy']->btns['BEZ_PROBLEM.'] = (object)array('value'=>'NORMAL');
  125. }
  126. if (array_key_exists('A_STATUS', $this->_cols)) {
  127. $fltrs['Status'] = new stdClass();
  128. $fltrs['Status']->icon = 'icon-question-sign';
  129. $fltrs['Status']->btns = array();
  130. $fltrs['Status']->btns['OCZEKUJACY'] = (object)array('value'=>'WAITING');
  131. $fltrs['Status']->btns['AKTYWNI'] = (object)array('value'=>'AKTYWNI');
  132. }
  133. if (array_key_exists('L_APPOITMENT_DATE', $this->_cols)) {
  134. $fltrs['Spotkania'] = new stdClass();
  135. $fltrs['Spotkania']->icon = 'icon-calendar';
  136. $fltrs['Spotkania']->btns = array();
  137. $fltrs['Spotkania']->btns['STARE'] = (object)array('value'=>'OLD');
  138. $fltrs['Spotkania']->btns['ZARAZ'] = (object)array('value'=>'NOW');
  139. $fltrs['Spotkania']->btns['DZISIAJ'] = (object)array('value'=>'TODAY');
  140. $fltrs['Spotkania']->btns['BRAK'] = (object)array('value'=>'BRAK');
  141. }
  142. if ($this->isAccessFltrAllowed()) {
  143. $fltrs['Access'] = new stdClass();
  144. $fltrs['Access']->icon = 'icon-lock';
  145. $fltrs['Access']->btns = array();
  146. $fltrs['Access']->btns['UKRYJ'] = (object)array('value'=>'HIDE');
  147. }
  148. return $fltrs;
  149. }
  150. function _parseSpecialFilter($fltr, $value) {
  151. $sqlFltr = "";
  152. switch ($fltr) {
  153. case 'Problemy':
  154. if (array_key_exists('A_PROBLEM', $this->_cols)) {
  155. switch ($value) {
  156. case 'PROBLEM':
  157. $sqlFltr = " t.`A_PROBLEM`!='' ";
  158. break;
  159. case 'WARNING':
  160. $sqlFltr = " t.`A_PROBLEM`='WARNING' ";
  161. break;
  162. case 'NORMAL':
  163. $sqlFltr = " t.`A_PROBLEM`='' ";
  164. break;
  165. }
  166. }
  167. break;
  168. case 'Status':
  169. if (array_key_exists('A_STATUS', $this->_cols)) {
  170. switch ($value) {
  171. case 'WAITING':
  172. $sqlFltr = " t.`A_STATUS`='WAITING' ";
  173. break;
  174. case 'AKTYWNI':
  175. $sqlFltr = " t.`A_STATUS` in('NORMAL', 'WARNING') ";
  176. // TODO: $_SESSION['USERS_FILTER_STATUS_SQL']="and (( $thiss->DETECT_TABLE_NAME.A_STATUS='NORMAL' or $thiss->DETECT_TABLE_NAME.A_STATUS='WARNING' ) or ( $thiss->DETECT_TABLE_NAME.A_STATUS='OFF_SOFT' and $thiss->DETECT_TABLE_NAME.A_PROBLEM_DESC not like '%odla%fizy%' and $thiss->DETECT_TABLE_NAME.A_PROBLEM!='' ) or ( $thiss->DETECT_TABLE_NAME.A_STATUS='OFF_SOFT' and $thiss->DETECT_TABLE_NAME.A_PROBLEM='' )) ";
  177. // if ($thiss->DETECT_TABLE_NAME == 'KSIEG_DOKUMENTY') $_SESSION['USERS_FILTER_STATUS_SQL']="and ( $thiss->DETECT_TABLE_NAME.A_STATUS='NORMAL' or $thiss->DETECT_TABLE_NAME.A_STATUS='WARNING' ) ";
  178. break;
  179. }
  180. }
  181. break;
  182. case 'Spotkania':
  183. if (array_key_exists('L_APPOITMENT_DATE', $this->_cols)) {
  184. switch ($value) {
  185. case 'OLD':
  186. $sqlFltr = " UNIX_TIMESTAMP(t.`L_APPOITMENT_DATE`)<UNIX_TIMESTAMP(now()) and t.`L_APPOITMENT_DATE`!='' ";
  187. break;
  188. case 'NOW':
  189. $sqlFltr = " UNIX_TIMESTAMP(t.`L_APPOITMENT_DATE`)<UNIX_TIMESTAMP(now())+3600 and UNIX_TIMESTAMP(t.`L_APPOITMENT_DATE`)>UNIX_TIMESTAMP(now())-3600 ";
  190. break;
  191. case 'TODAY':
  192. $start = mktime(0,0,0, date("m"), date("d"), date("Y"));
  193. $end = mktime(0,0,0, date("m"), date("d") + 1, date("Y"));
  194. $sqlFltr = " UNIX_TIMESTAMP(t.`L_APPOITMENT_DATE`)>'{$start}' and UNIX_TIMESTAMP(t.`L_APPOITMENT_DATE`)<'{$end}' ";
  195. break;
  196. case 'TOMORROW':
  197. $start = mktime(0,0,0, date("m"), date("d") + 1, date("Y"));
  198. $end = mktime(0,0,0, date("m"), date("d") + 2, date("Y"));
  199. $sqlFltr = " UNIX_TIMESTAMP(t.`L_APPOITMENT_DATE`)>'{$start}' and UNIX_TIMESTAMP(t.`L_APPOITMENT_DATE`)<'{$end}' ";
  200. break;
  201. case 'YESTERDAY':
  202. $start = mktime(0,0,0, date("m"), date("d") - 1, date("Y"));
  203. $end = mktime(0,0,0, date("m"), date("d") - 2, date("Y"));
  204. $sqlFltr = " UNIX_TIMESTAMP(t.`L_APPOITMENT_DATE`)>'{$start}' and UNIX_TIMESTAMP(t.`L_APPOITMENT_DATE`)<'{$end}' ";
  205. break;
  206. case 'BRAK':
  207. $start = mktime(0,0,0, date("m"), date("d") - 1, date("Y"));
  208. $end = mktime(0,0,0, date("m"), date("d") - 2, date("Y"));
  209. $sqlFltr = " t.`L_APPOITMENT_DATE`='' ";
  210. break;
  211. }
  212. }
  213. break;
  214. case 'Access':
  215. if ($this->isAccessFltrAllowed()) {
  216. $usrAclGroups = User::getLdapGroupsNames();
  217. $usrAclGroups[] = '';
  218. $sqlUsrAclGroups = "'" . implode("','", $usrAclGroups) . "'";
  219. $sqlFltr = "
  220. t.`{$this->_fieldGroupWrite}` in({$sqlUsrAclGroups})
  221. and t.`{$this->_fieldGroupRead}` in({$sqlUsrAclGroups})
  222. ";
  223. }
  224. break;
  225. default:
  226. }
  227. /*
  228. //USERS_FILTER_PROBLEM
  229. // PROBLEMY https://biuro.biall-net.pl/SE/se-dev/index.php?FUNCTION_INIT=USERS_FILTER_PROBLEM&USERS_FILTER_PROBLEM=PROBLEM
  230. // OSTRZEZENIA https://biuro.biall-net.pl/SE/se-dev/index.php?FUNCTION_INIT=USERS_FILTER_PROBLEM&USERS_FILTER_PROBLEM=WARNING
  231. // BEZ_PROBLEM. https://biuro.biall-net.pl/SE/se-dev/index.php?FUNCTION_INIT=USERS_FILTER_PROBLEM&USERS_FILTER_PROBLEM=NORMAL
  232. // KASUJ-FILTR https://biuro.biall-net.pl/SE/se-dev/index.php?FUNCTION_INIT=USERS_FILTER_PROBLEM&USERS_FILTER_PROBLEM=
  233. //USERS_FILTER_STATUS
  234. // OCZEKUJACY https://biuro.biall-net.pl/SE/se-dev/index.php?FUNCTION_INIT=USERS_FILTER_STATUS&USERS_FILTER_STATUS=WAITING
  235. // AKTYWNI https://biuro.biall-net.pl/SE/se-dev/index.php?FUNCTION_INIT=USERS_FILTER_STATUS&USERS_FILTER_STATUS=AKTYWNI
  236. // KASUJ-FILTR https://biuro.biall-net.pl/SE/se-dev/index.php?FUNCTION_INIT=USERS_FILTER_STATUS&USERS_FILTER_STATUS=
  237. //USERS_FILTER_APPOINTMENT
  238. // A_STARE https://biuro.biall-net.pl/SE/se-dev/index.php?FUNCTION_INIT=USERS_FILTER_APPOINTMENT&USERS_FILTER_APPOINTMENT=OLD
  239. // A_ZARAZ https://biuro.biall-net.pl/SE/se-dev/index.php?FUNCTION_INIT=USERS_FILTER_APPOINTMENT&USERS_FILTER_APPOINTMENT=NOW
  240. // A_DZISIAJ https://biuro.biall-net.pl/SE/se-dev/index.php?FUNCTION_INIT=USERS_FILTER_APPOINTMENT&USERS_FILTER_APPOINTMENT=TODAY
  241. // APP_ALL https://biuro.biall-net.pl/SE/se-dev/index.php?FUNCTION_INIT=USERS_FILTER_APPOINTMENT&USERS_FILTER_APPOINTMENT=
  242. // btn class: active, disabled
  243. {// USERS_FILTER_PROBLEM
  244. var groupHtml = $('<div class="btn-group"></div>');
  245. $('<button class="btn btn-mini" title="Problemy"><i class="icon-warning-sign"></i></button>').appendTo(groupHtml);
  246. $('<button class="btn btn-mini">PROBLEMY</button>').appendTo(groupHtml);
  247. $('<button class="btn btn-mini">OSTRZEZENIA</button>').appendTo(groupHtml);
  248. $('<button class="btn btn-mini active">BEZ_PROBLEM.</button>').appendTo(groupHtml);
  249. $('<button class="btn btn-mini disabled" title="Kasuj filtr"><i class="icon-remove"></i></button>').appendTo(groupHtml);
  250. groupHtml.appendTo(_headSpecialFilter);
  251. }
  252. {// USERS_FILTER_STATUS
  253. var groupHtml = $('<div class="btn-group"></div>');
  254. $('<button class="btn btn-mini" title="Status"><i class="icon-question-sign"></i></button>').appendTo(groupHtml);
  255. $('<button class="btn btn-mini">OCZEKUJACY</button>').appendTo(groupHtml);
  256. $('<button class="btn btn-mini">AKTYWNI</button>').appendTo(groupHtml);
  257. $('<button class="btn btn-mini disabled" title="Kasuj filtr"><i class="icon-remove"></i></button>').appendTo(groupHtml);
  258. groupHtml.appendTo(_headSpecialFilter);
  259. }
  260. {// USERS_FILTER_APPOINTMENT
  261. var groupHtml = $('<div class="btn-group"></div>');
  262. $('<button class="btn btn-mini" title="Spotkania"><i class="icon-calendar"></i></button>').appendTo(groupHtml);
  263. $('<button class="btn btn-mini">A_STARE</button>').appendTo(groupHtml);
  264. $('<button class="btn btn-mini">A_ZARAZ</button>').appendTo(groupHtml);
  265. $('<button class="btn btn-mini active">A_DZISIAJ</button>').appendTo(groupHtml);
  266. $('<button class="btn btn-mini disabled" title="Kasuj filtr"><i class="icon-remove"></i></button>').appendTo(groupHtml);// To samo co KASUJ-FILTR
  267. groupHtml.appendTo(_headSpecialFilter);
  268. }
  269. */
  270. return $sqlFltr;
  271. }
  272. private function isColTypeNumber($colName) {
  273. if ($colName == 'ID') {
  274. return true;
  275. }
  276. $type = V::get($colName, null, $this->_col_types);
  277. if(V::get('DBG_DS', 0, $_GET) > 0){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">type['.$colName.'] (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r(array('type'=>$type, '!empty'=>(!empty($type['type']['type']))));echo'</pre>'."\n\n";}
  278. if (!empty($type['type'])) {
  279. $sqlType = $type['type'];
  280. if (substr($sqlType, 0, 3) == 'int'
  281. || substr($sqlType, 0, 7) == 'tinyint'
  282. || substr($sqlType, 0, 8) == 'smallint'
  283. ) {
  284. return true;
  285. }
  286. }
  287. return false;
  288. }
  289. function _parse_sql_where($params = array()) {
  290. $sql_where = '';
  291. // ... parse filters
  292. $sql_where_and = array();
  293. foreach ($params as $k => $v) {
  294. if (strlen($k) > 3 && substr($k, 0, 2) == 'f_') {
  295. //$v = trim($v, '% ');
  296. //$sql_where_and []= "t.`" . substr($k, 2) . "` like '%" . DB::_($v) . "%'";
  297. $fldName = substr($k, 2);
  298. if (substr($v, 0, 1) == '=') {
  299. $v = $this->_db->_(substr($v, 1));
  300. if (strlen($v)) $sql_where_and []= "t.`{$fldName}`='{$v}'";
  301. }
  302. else if (substr($v, 0, 1) == '!') {
  303. $v = $this->_db->_(substr($v, 1));
  304. if (strlen($v)) $sql_where_and []= "t.`{$fldName}` not like '{$v}'";
  305. }
  306. else if (substr($v, 0, 2) == '<=') {
  307. $v = $this->_db->_(substr($v, 2));
  308. if (strlen($v)) $sql_where_and []= "t.`{$fldName}`<='{$v}'";
  309. }
  310. else if (substr($v, 0, 2) == '>=') {
  311. $v = $this->_db->_(substr($v, 2));
  312. if (strlen($v)) $sql_where_and []= "t.`{$fldName}`>='{$v}'";
  313. }
  314. else if (substr($v, 0, 1) == '<') {
  315. $v = $this->_db->_(substr($v, 1));
  316. if (strlen($v)) $sql_where_and []= "t.`{$fldName}`<'{$v}'";
  317. }
  318. else if (substr($v, 0, 1) == '>') {
  319. $v = $this->_db->_(substr($v, 1));
  320. if (strlen($v)) $sql_where_and []= "t.`{$fldName}`>'{$v}'";
  321. }
  322. else if (false !== strpos($v, '%')) {
  323. $sql_where_and []= "t.`{$fldName}` like '{$v}'";
  324. }
  325. else if ($this->isColTypeNumber($fldName)) {
  326. $v = $this->_db->_($v);
  327. $sql_where_and []= "t.`{$fldName}`='{$v}'";
  328. }
  329. else {
  330. $searchWords = explode(' ', $v);
  331. $sqlWhereWords = array();
  332. if (!empty($searchWords)) {
  333. foreach ($searchWords as $word) {
  334. if (!empty($word)) {
  335. $word = $this->_db->_($word);
  336. $sqlWhereWords []= "t.`{$fldName}` like '%{$word}%'";
  337. }
  338. }
  339. }
  340. if (!empty($searchWords)) {
  341. $sql_where_and []= "(" . implode(" and ", $sqlWhereWords) . ")";
  342. }
  343. }
  344. }
  345. else if (strlen($k) > 4 && substr($k, 0, 3) == 'sf_') {
  346. $sqlFltr = $this->_parseSpecialFilter(substr($k, 3), $v);
  347. if (!empty($sqlFltr)) {
  348. $sql_where_and []= $sqlFltr;
  349. }
  350. }
  351. }
  352. if (!empty($sql_where_and)) {
  353. $sql_where = implode(" and ", $sql_where_and);
  354. }
  355. if (!$sql_where) $sql_where = "1=1";
  356. if(V::get('DBG_DS', 0, $_GET) > 1){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">sql_where (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($sql_where);echo'</pre>'."\n\n";}
  357. return $sql_where;
  358. }
  359. function get_item($id) {// TODO: RMME
  360. $this->getItem($id);
  361. }
  362. public function getItem($id) {
  363. $ret = null;
  364. $sql_cols = $this->_get_sql_cols();
  365. $id = intval($id);
  366. $sql = "select {$sql_cols}
  367. from {$this->_tbl} as t
  368. where t.`ID`='{$id}'
  369. ";
  370. $res = $this->_db->query($sql);
  371. if ($r = $this->_db->fetch($res)) {
  372. $ret = $r;
  373. }
  374. return $ret;
  375. }
  376. function get_items($params = array()) {// TODO: RMME
  377. $this->getItems($params);
  378. }
  379. public function getItems($params = array()) {
  380. $ret = array();
  381. $sql_limit = V::get('limit', $this->_default_sql_limit, $params, 'int');
  382. $sql_offset = V::get('limitstart', 0, $params, 'int');
  383. $sql_order_by = V::get('order_by', '', $params);
  384. if ($sql_order_by) {
  385. $sql_order_dir = V::get('order_dir', '', $params);
  386. // prevent from sorting by special columns
  387. if (!array_key_exists($sql_order_by, $this->_cols)) {
  388. $sql_order_by = null;
  389. $sql_order_dir = null;
  390. }
  391. }
  392. if ($sql_order_by) {
  393. $sql_order_by = "order by t.`{$sql_order_by}`";
  394. if ($sql_order_dir) {
  395. $sql_order_by = "{$sql_order_by} {$sql_order_dir}";
  396. }
  397. }
  398. $sql_cols = $this->_get_sql_cols();
  399. $sql_where = $this->_parse_sql_where($params);
  400. $sql = "select {$sql_cols}
  401. from {$this->_tbl} as t
  402. where {$sql_where}
  403. {$sql_order_by}
  404. limit {$sql_limit} offset {$sql_offset}
  405. ";
  406. $res = $this->_db->query($sql);
  407. while ($r = $this->_db->fetch($res)) {
  408. $ret[$r->ID] = $r;
  409. }
  410. return $ret;
  411. }
  412. function get_hist_items($id) {// TODO: RMME
  413. $this->getHistItems($id);
  414. }
  415. public function getHistItems($id, $params = array()) {
  416. $ret = array();
  417. $sql_tbl = $this->_tbl . "_HIST";
  418. $sql_cols = $this->_get_sql_cols();
  419. $sql_where = "t.`ID_USERS2`='{$id}'";
  420. $paramNotEmptyFlds = V::get('notEmptyFlds', '', $params);
  421. if (!empty($paramNotEmptyFlds) && is_array($paramNotEmptyFlds)) {
  422. $sqlWhereOr = array();
  423. foreach ($paramNotEmptyFlds as $fldName) {
  424. if (array_key_exists($fldName, $this->_cols)) {
  425. $sqlWhereOr[] = "t.`{$fldName}`!='N/S;'";
  426. }
  427. }
  428. if (!empty($sqlWhereOr)) $sql_where .= "\n and (" . implode(" or ", $sqlWhereOr) . ")";
  429. }
  430. $sql = "select {$sql_cols}
  431. from {$sql_tbl} as t
  432. where {$sql_where}
  433. order by ID DESC
  434. ";
  435. if(V::get('DBG_DS', 0, $_GET) > 2){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">sql (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($sql);echo'</pre>'."\n\n";}
  436. $res = $this->_db->query($sql);
  437. while ($r = $this->_db->fetch($res)) {
  438. $r->_author = $r->A_RECORD_UPDATE_AUTHOR;
  439. $r->_created = $r->A_RECORD_UPDATE_DATE;
  440. if (!$r->_author || $r->_author == 'N/S;') {
  441. $r->_author = $r->A_RECORD_CREATE_AUTHOR;
  442. }
  443. if (!$r->_created || $r->_created == 'N/S;') {
  444. $r->_created = $r->A_RECORD_CREATE_DATE;
  445. }
  446. $ret[$r->ID] = $r;
  447. }
  448. return $ret;
  449. }
  450. function get_total($params = array()) {// TODO: RMME
  451. $this->getTotal($params);
  452. }
  453. public function getTotal($params = array()) {
  454. $ret = 0;
  455. $sql_where = $this->_parse_sql_where($params);
  456. $sql = "select count(1) as cnt
  457. from {$this->_tbl} as t
  458. where {$sql_where}
  459. ";
  460. $res = $this->_db->query($sql);
  461. if ($r = $this->_db->fetch($res)) {
  462. $ret = $r->cnt;
  463. }
  464. return $ret;
  465. }
  466. function set_sql_where($sql_where) {
  467. $this->_sql_where = $sql_where;
  468. }
  469. function set_field_sql_type($field, $sql_type) {
  470. $this->_fields_type[$field] = $sql_type;
  471. }
  472. function get_field_sql_type($field) {
  473. if (array_key_exists($field, $this->_fields_type)) {
  474. return $this->_fields_type[$field];
  475. }
  476. return 'varchar(255)';
  477. }
  478. function set_field_perm($field, $perm) {
  479. $this->_fields_perm[$field] = $perm;
  480. }
  481. function get_field_perm($field) {
  482. if (array_key_exists($field, $this->_fields_perm)) {
  483. return $this->_fields_perm[$field];
  484. }
  485. return '';
  486. }
  487. function field_allow_write($field_name) {
  488. return (strpos($this->get_field_perm($field_name), 'W') !== false)? true : false;
  489. }
  490. function field_allow_read($field_name) {
  491. return (strpos($this->get_field_perm($field_name), 'R') !== false)? true : false;
  492. }
  493. function field_allow_create($field_name) {
  494. return (strpos($this->get_field_perm($field_name), 'C') !== false)? true : false;
  495. }
  496. public function add_col($col_name, $label = '', $type = 'string') {
  497. if (!$label) $label = $col_name;
  498. $this->_cols [$col_name] = $label;
  499. $this->_col_types [$col_name] = $type;
  500. }
  501. public function addCol($col_name) {
  502. $this->_cols[$col_name] = $col_name;
  503. }
  504. function count() {
  505. $ret = 0;
  506. $sql_where = ($this->_sql_where)? $this->_sql_where : "1=1";
  507. $sql = "select count(1) as cnt
  508. from `{$this->_tbl}`
  509. where {$sql_where}
  510. ";
  511. $res = $this->_db->query($sql);
  512. if ($r = $this->_db->fetch($res)) {
  513. $ret = $r->cnt;
  514. }
  515. return $ret;
  516. }
  517. function fetch_list($limit = 10, $offset = 0) {
  518. $ret = array();
  519. $this->_sql_limit = $limit;
  520. $this->_sql_offset = $offset;
  521. $sql_cols = (!empty($this->_cols))? implode(',', array_keys($this->_cols)) : "*";
  522. $sql_where = ($this->_sql_where)? $this->_sql_where : "1=1";
  523. $sql = "
  524. select {$sql_cols}
  525. from {$this->_tbl}
  526. where {$sql_where}
  527. limit {$this->_sql_limit} offset {$this->_sql_offset}
  528. ";
  529. $res = $this->_db->query($sql);
  530. while ($r = $this->_db->fetch($res)) {
  531. $ret [$r->ID] = $r;
  532. }
  533. return $ret;
  534. }
  535. function field_check_value($field_name, $val) {
  536. if (!$this->field_allow_write($field_name)) {
  537. return false;
  538. }
  539. // post verify
  540. // get type, and check if value is correct
  541. // TODO: if typespecial use it
  542. return true;
  543. }
  544. function save_item(&$item, $values, $prefix) {
  545. if (!$item->ID) {
  546. return null;
  547. }
  548. $sql_obj = new stdClass();
  549. $sql_obj->ID = $item->ID;
  550. foreach ($values as $k_field_with_prefix => $v_field) {
  551. if (substr($k_field_with_prefix, 0, strlen($prefix)) != $prefix) {
  552. continue;
  553. }
  554. $k_field = substr($k_field_with_prefix, strlen($prefix));
  555. if ($this->field_allow_write($k_field)) {
  556. if ($this->field_check_value($k_field, $v_field)) {
  557. $sql_obj->$k_field = $v_field;
  558. }
  559. }
  560. }
  561. $affected = $this->_db->PDATE_OBJ($this->_tbl, $sql_obj);
  562. return $affected;
  563. }
  564. function add_item($values, $prefix) {
  565. $sql_obj = new stdClass();
  566. foreach ($values as $k_field_with_prefix => $v_field) {
  567. if (substr($k_field_with_prefix, 0, strlen($prefix)) != $prefix) {
  568. continue;
  569. }
  570. $k_field = substr($k_field_with_prefix, strlen($prefix));
  571. if ($this->field_allow_create($k_field)) {
  572. if ($this->field_check_value($k_field, $v_field)) {
  573. $sql_obj->$k_field = $v_field;
  574. }
  575. }
  576. }
  577. $insert_id = $this->_db->ADD_NEW_OBJ($this->_tbl, $sql_obj);
  578. return $insert_id;
  579. }
  580. }