UserMsgs.php 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161
  1. <?php
  2. Lib::loadClass('Router');
  3. Lib::loadClass('RouteBase');
  4. Lib::loadClass('TypespecialVariable');
  5. Lib::loadClass('ProcesHelper');
  6. Lib::loadClass('UsersHelper');
  7. Lib::loadClass('UI');
  8. class Route_UserMsgs extends RouteBase {
  9. var $_listLimit = 20;
  10. function handleAuth() {
  11. if (!User::logged()) {
  12. User::authByRequest();
  13. }
  14. if ($postTask = V::get('_postTask', '', $_POST)) {
  15. $postFunction = "{$postTask}PostTask";
  16. if (!method_exists($this, $postFunction)) {
  17. S::saveUserMessage('AlertDangerException', "post task not exists '{$postTask}'");
  18. } else {
  19. $this->$postFunction($_POST);
  20. }
  21. }
  22. }
  23. function defaultAction() { UI::layout([ $this, 'defaultView' ]); }
  24. function defaultView() {
  25. $usrLogin = User::getLogin();
  26. //$this->menu();
  27. $this->userMsgs($usrLogin);
  28. }
  29. function menu() {
  30. $usrLogin = User::getLogin();
  31. echo UI::h('ul', [], [
  32. UI::h('li', [], "TODO: ..."),
  33. ]);
  34. }
  35. function userMsgs($usrLogin) {
  36. $msgsList = $this->getMsgs('inbox', $usrLogin);
  37. $totalReadMsgs = 0;
  38. $totalUnreadMsgs = 0;
  39. foreach ($msgsList as $ind => $msg) {
  40. if ($msg['_read']) {
  41. $totalReadMsgs++;
  42. } else {
  43. $totalUnreadMsgs++;
  44. }
  45. }
  46. $sentMsgsList = $this->getMsgs('sent', $usrLogin);
  47. $removedMsgsList = $this->getMsgs('removed', $usrLogin);
  48. ?>
  49. <style type="text/css">
  50. .tblMsgsListItem { cursor:pointer; }
  51. </style>
  52. <div class="container">
  53. <h3><i class="glyphicon glyphicon-envelope"></i> Wiadomości <code><?php echo $usrLogin; ?></code></h3>
  54. <div>
  55. <ul class="nav nav-tabs" role="tablist">
  56. <!--
  57. <li>
  58. <a href="#tbl-msgs-compose"><i class="glyphicon glyphicon-plus"></i> Nowa wiadomość</a>
  59. </li>
  60. -->
  61. <li role="presentation" class="active"><a href="#odebrane" aria-controls="odebrane" role="tab" data-toggle="tab">Odebrane <em>(<?php echo $totalUnreadMsgs; ?>)</em></a></li>
  62. <li role="presentation"><a href="#wyslane" aria-controls="wyslane" role="tab" data-toggle="tab">Wysłane</em></a></li>
  63. <li role="presentation"><a href="#kosz" aria-controls="kosz" role="tab" data-toggle="tab">Kosz</em></a></li>
  64. </ul>
  65. <div class="tab-content" style="margin-bottom:15px">
  66. <div role="tabpanel" class="tab-pane active" id="odebrane" style="border-style:none solid solid solid; border-width:1px; border-color:#ddd;">
  67. <?php $this->_printUserMsgsList('inbox', $msgsList, $usrLogin); ?>
  68. </div>
  69. <div role="tabpanel" class="tab-pane" id="wyslane" style="border-style:none solid solid solid; border-width:1px; border-color:#ddd;">
  70. <?php $this->_printUserMsgsList('sent', $sentMsgsList, $usrLogin); ?>
  71. </div>
  72. <div role="tabpanel" class="tab-pane" id="kosz" style="border-style:none solid solid solid; border-width:1px; border-color:#ddd;">
  73. <?php $this->_printUserMsgsList('removed', $removedMsgsList, $usrLogin); ?>
  74. </div>
  75. </div>
  76. </div>
  77. <!--
  78. <div class="panel panel-default" id="tbl-msgs-compose">
  79. <div class="panel-heading">Wyślij nową wiadomość</div>
  80. <div class="panel-body">
  81. <?php if (!empty($arrorsList)) : ?>
  82. <?php foreach ($arrorsList as $errMsg) : ?>
  83. <div class="alert alert-danger"><?php echo $errMsg; ?></div>
  84. <?php endforeach; ?>
  85. <?php endif; ?>
  86. <?php $this->_printMsgForm($args); ?>
  87. </div>
  88. </div>
  89. -->
  90. </div>
  91. <script>
  92. var DBG = 0;
  93. var DBG1 = 1;
  94. function tblMsgsLoadMoreRows(n) {
  95. var nNode = jQuery(n),
  96. lastMsgId = nNode.data('last_msg_id'),
  97. listType = nNode.data('list_type')
  98. ;
  99. DBG && console.log("DBG:tblMsgsLoadMoreRows ", { lastMsgId, listType });
  100. nNode.blur();
  101. function tblMsgsSetNoMoreRows(btnLoadMoreNode) {
  102. btnLoadMoreNode.closest('td').css({color:'silver'}).html('Brak starszych wiadomości');
  103. }
  104. if (lastMsgId <= 0) {
  105. tblMsgsSetNoMoreRows(nNode);
  106. }
  107. function tblMsgsAddMsgToList(msg, btnLoadMoreNode, listType) {
  108. var tbodyNode = btnLoadMoreNode.closest('table').children('tbody'),
  109. trNode = jQuery('<tr></tr>'),
  110. tdIdNode = jQuery('<td></td>'),
  111. tdMsgNode = jQuery('<td></td>'),
  112. tdDateNode = jQuery('<td style="white-space:nowrap;"></td>'),
  113. actionTask = (listType == 'inbox')? 'read' : 'view',
  114. msgLink = ''
  115. ;
  116. trNode.addClass('tblMsgsListItem');
  117. if (msg['_read']) trNode.addClass('active');
  118. if ('read' === actionTask || 'view' === actionTask) {
  119. msgLink = '<?php echo Request::getPathUri() . 'index.php?_route=UserMsgs'; ?>';
  120. msgLink += '&usrLogin=<?php echo $usrLogin; ?>';
  121. msgLink += '&id=' + msg['_raw']['ID'];
  122. msgLink += '&_task=' + actionTask;
  123. trNode.attr('onclick', "window.location.href='" + msgLink + "'");
  124. }
  125. tdIdNode.append(msg['_raw']['ID']);
  126. tdIdNode.appendTo(trNode);
  127. tdMsgNode.append('<div style="overflow:hidden; white-space:nowrap; text-overflow:ellipsis;">' + msg['message'] + '</div>');
  128. msgMetaInfo = 'od ' + msg['_raw']['A_RECORD_CREATE_AUTHOR'] + ' do ';
  129. if ('everyone' == msg['_raw']['userTargetType']) {
  130. msgMetaInfo += 'wszystkich';
  131. } else if ('user' == msg['_raw']['userTargetType']) {
  132. msgMetaInfo += msg['_raw']['userTargetName'];
  133. } else if ('group' == msg['_raw']['userTargetType']) {
  134. msgMetaInfo += 'grupy ' + msg['_raw']['userTargetName'];
  135. }
  136. tdMsgNode.append('<div class="text-muted" style="font-style:italic;">' + msgMetaInfo + '</div>');
  137. tdMsgNode.appendTo(trNode);
  138. tdDateNode.append(msg['_raw']['A_RECORD_CREATE_DATE']);
  139. if (msg['_readDate']) {
  140. tdDateNode.append('<div class="text-muted" style="font-style:italic" title="Przeczytano ' + msg['_readDate'] + '">' + msg['_readDate'] + '</div>');
  141. } else {
  142. tdDateNode.append('<div class="text-muted" style="font-style:italic" title="Wiadomość nie została jeszcze odczytana">nieodczytana</div>');
  143. }
  144. tdDateNode.appendTo(trNode);
  145. trNode.hide();
  146. trNode.appendTo(tbodyNode);
  147. trNode.show('slow');
  148. };
  149. jQuery.ajax({
  150. data: {},
  151. dataType: 'json',
  152. type: "POST",
  153. url: 'index.php?_route=UserMsgs&_task=loadMoreRows&listType=' + listType + '&lastMsgId=' + lastMsgId + '&usrLogin=<?php echo $usrLogin; ?>'
  154. })
  155. .done(function(data, textStatus, jqXHR) {
  156. var listLimit = <?php echo $this->_listLimit; ?>,
  157. i = 0,
  158. lastMsgId = 0,
  159. hasMore = false
  160. ;
  161. DBG && console.log("DBG:tblMsgsLoadMoreRows fetched ", { data });
  162. if (!data || !data.msgs || !data.keysOrder) {
  163. jQuery.notify('Wystąpiły błędy podczas pobierania listy wiadomości', 'error');
  164. return false;
  165. }
  166. data.keysOrder.forEach(function(key) {
  167. if (i < listLimit) {
  168. lastMsgId = key;
  169. tblMsgsAddMsgToList(data.msgs[key], nNode, listType);
  170. } else {
  171. hasMore = true;
  172. }
  173. i++;
  174. });
  175. if (!hasMore) {
  176. tblMsgsSetNoMoreRows(nNode);
  177. }
  178. nNode.data('last_msg_id', lastMsgId);
  179. })
  180. .fail(function(jqXHR) {
  181. if (jqXHR.responseJSON) {
  182. jQuery.notify('Nie udało się pobrać listy wiadomości', 'error');
  183. }
  184. else {
  185. var txt = jqXHR.responseText || 'Nie udało się pobrać listy wiadomości';
  186. if (jqXHR.status == 404) {
  187. jQuery.notify(jqXHR.responseText, 'error');
  188. } else {
  189. jQuery.notify(jqXHR.responseText, 'warn');
  190. }
  191. }
  192. });
  193. }
  194. </script>
  195. <?php
  196. //DBG::_(true, true, "_POST", $_POST, __CLASS__, __FUNCTION__, __LINE__);
  197. //DBG::_(true, true, "tblAcl", $tblAcl, __CLASS__, __FUNCTION__, __LINE__);
  198. //DBG::_(true, true, "record", $record, __CLASS__, __FUNCTION__, __LINE__);
  199. //DBG::_(true, true, "msgsList", $msgsList, __CLASS__, __FUNCTION__, __LINE__);
  200. //throw new Exception("TODO: ...");
  201. }
  202. function loadMoreRowsAction() {
  203. $usrLogin = V::get('usrLogin', '', $_GET, 'word');
  204. $lastMsgId = V::get('lastMsgId', 0, $_GET, 'int');
  205. $listType = V::get('listType', '', $_GET, 'word');
  206. if (!$usrLogin) throw new HttpException("Wrong param login", 404);
  207. if ($lastMsgId <= 0) throw new HttpException("Wrong param lastMsgId", 404);
  208. if (!in_array($listType, array('inbox','sent','removed'))) throw new HttpException("Wrong param listType", 404);
  209. $resultData = new stdClass();
  210. $resultData->msgs = $this->getMsgs($listType, $usrLogin, $lastMsgId);
  211. $resultData->keysOrder = array_keys($resultData->msgs);
  212. echo json_encode($resultData);
  213. }
  214. function _printUserMsgsList($listType, $msgsList, $usrLogin) {
  215. $msgsTotal = count($msgsList);
  216. $listLimit = $this->_listLimit;
  217. $lastMsgId = 0;
  218. $viewMsgList = array_slice($msgsList, 0, $this->_listLimit, $preserve_keys = true);
  219. if ($msgsTotal > $listLimit) {
  220. $msgIds = array_slice(array_keys($msgsList), 0, $listLimit);
  221. $lastMsgId = array_pop($msgIds);
  222. }
  223. $actionTask = ($listType == 'inbox')? 'read' : 'view';
  224. echo UI::h('table', [ 'class' => "tblMsgsList table table-hovered", 'style' => "margin-bottom:0; table-layout:fixed" ], [
  225. UI::h('thead', [], [
  226. UI::h('tr', [], [
  227. UI::h('th', [ 'style' => "width:60px" ], "#"),
  228. UI::h('th', [], "wiadomość"),
  229. UI::h('th', [ 'style' => "width:130px" ], "data"),
  230. ]),
  231. ]),
  232. ($msgsTotal > $listLimit)
  233. ? UI::h('tfoot', [], [
  234. UI::h('tr', [ 'class' => "active" ], [
  235. UI::h('td', [ 'colspan' => "3", 'style' => "text-align:center" ], [
  236. UI::h('button', [
  237. 'class' => "btn btn-link",
  238. 'data-last_msg_id' => $lastMsgId,
  239. 'data-list_type' => $listType,
  240. 'onclick' => "return tblMsgsLoadMoreRows(this);",
  241. ], "pobierz starsze wiadomości ..."),
  242. ]),
  243. ]),
  244. ])
  245. : ''
  246. ,
  247. UI::h('tbody', [],
  248. ($msgsTotal <= 0)
  249. ? UI::h('tr', [], [
  250. UI::h('td', [ 'colspan' => "3" ], [
  251. UI::h('em', [ 'class' => "text-muted", 'style' => "padding-left:60px;" ], "Brak wiadomości"),
  252. ]),
  253. ])
  254. : array_map(function ($msg) use ($actionTask, $usrLogin) {
  255. $msgLink = ('read' == $actionTask || 'view' == $actionTask)
  256. ? $this->getLink($actionTask, [ 'id' => $msg['_raw']->ID, 'usrLogin' => $usrLogin ])
  257. : null
  258. ;
  259. $jsOnClick = ($msgLink)
  260. ? "window.location.href='{$msgLink}'"
  261. : ''
  262. ;
  263. return UI::h('tr', [ 'onclick' => $jsOnClick, 'class' => "tblMsgsListItem " . ($msg['_read'] ? 'active' : '') ], [
  264. UI::h('td', [], $msg['_raw']->ID),
  265. UI::h('td', [], [
  266. UI::h('div', [ 'style' => "overflow:hidden; white-space:nowrap; text-overflow:ellipsis" ], htmlspecialchars($msg['message'])),
  267. UI::h('div', [ 'class' => "text-muted", 'style' => "font-style:italic"], [
  268. "od {$msg['_raw']->A_RECORD_CREATE_AUTHOR} do " . $this->getOutMsgTarget($msg['_raw']),
  269. ]),
  270. ]),
  271. UI::h('td', [ 'style' => "white-space:nowrap" ], [
  272. $msg['_raw']->A_RECORD_CREATE_DATE,
  273. ($msg['_readDate'])
  274. ? UI::h('div', [ 'class' => "text-muted", 'style' => "font-style:italic", 'title' => "Przeczytano {$msg['_readDate']}" ], $msg['_readDate'])
  275. : UI::h('div', [ 'class' => "text-muted", 'style' => "font-style:italic", 'title' => "Wiadomość nie została jeszcze odczytana" ], "nieodczytana")
  276. ,
  277. ]),
  278. ]);
  279. }, $viewMsgList)
  280. ),
  281. ]);
  282. }
  283. function getOutMsgTarget($msg) {
  284. switch ($msg->userTargetType) {
  285. case 'everyone': return "wszystkich";
  286. case 'user': return $msg->userTargetName;
  287. case 'group': return "grupy {$msg->userTargetName}";
  288. default: return '???';
  289. }
  290. }
  291. function getMsgs($filterType, $usrLogin, $lastMsgId = null, $fromTime = null) {
  292. $lastMsgId = (int)$lastMsgId;
  293. $msgsRoute = Router::getRoute('Msgs');
  294. $msgsList = array();
  295. if (empty($usrLogin)) throw new Exception("No user login!");
  296. $sqlWhereAddFilter = "";
  297. if ($usrLogin == User::getLogin()) {
  298. $userGroupIds = User::getGroupsIds();
  299. } else {
  300. $userGroup = UsersHelper::getGroupByUserName($usrLogin);
  301. $userGroupIds = array_keys($userGroup);
  302. }
  303. $sqlFilerMsgsForUser = "
  304. m.`userTargetType` in('everyone')
  305. or (m.`userTargetType`='user' and m.`userTargetName`='{$usrLogin}')
  306. or (m.`userTargetType`='group' and m.`userTargetName` in(" . implode(",", $userGroupIds) . "))
  307. ";
  308. switch ($filterType) {
  309. case 'inbox':
  310. $sqlWhereAddFilter = "
  311. and ({$sqlFilerMsgsForUser})
  312. and m.`A_STATUS` in('WAITING', 'NORMAL')
  313. ";
  314. break;
  315. case 'unread':
  316. $sqlWhereAddFilter = "
  317. and ({$sqlFilerMsgsForUser})
  318. and m.`A_STATUS` in('WAITING')
  319. ";
  320. break;
  321. case 'sent':
  322. $sqlWhereAddFilter = "
  323. and m.`A_RECORD_CREATE_AUTHOR`='{$usrLogin}'
  324. and (m.`A_STATUS` in('WAITING', 'NORMAL')
  325. or (m.`A_STATUS`='OFF_HARD' and m.`A_RECORD_DELETE_AUTHOR`!='{$usrLogin}')
  326. )
  327. ";
  328. break;
  329. case 'removed':
  330. $sqlWhereAddFilter = "
  331. and (m.`A_RECORD_CREATE_AUTHOR`='{$usrLogin}'
  332. or ({$sqlFilerMsgsForUser})
  333. )
  334. and m.`A_STATUS` in('OFF_HARD', 'DELETED')
  335. ";
  336. break;
  337. default: throw new Exception("Unknown filter type");
  338. }
  339. if ($lastMsgId > 0) {
  340. $sqlWhereAddFilter .= "\n and m.`ID`<{$lastMsgId}";
  341. }
  342. if (!empty($fromTime)) {
  343. $sqlWhereAddFilter .= "\n and m.`A_RECORD_CREATE_DATE`>='{$fromTime}'";
  344. }
  345. $sqlLimit = $this->_listLimit + 1;
  346. $sql = "
  347. select m.*
  348. from `CRM_UI_MSGS` m
  349. where m.`uiTargetType` = 'default_db_table_record'
  350. {$sqlWhereAddFilter}
  351. order by m.`ID` DESC
  352. limit {$sqlLimit}
  353. ";
  354. return array_map(function ($row) {
  355. return [
  356. 'message' => $row['msg'],
  357. 'type' => $row['msgType'],
  358. '_raw' => (object)$row,
  359. '_read' => ('WAITING' != $row['A_STATUS']),
  360. '_readDate' => $row['actionExecutedTime'],
  361. ];
  362. }, DB::getPDO()->fetchAllByKey($sql, 'ID'));
  363. }
  364. function _validate($args) {
  365. $toType = V::get('to_type', '', $args);
  366. $to = V::get('to', '', $args);
  367. $msg = V::get('msg', '', $args);
  368. if (!in_array($toType, array('everyone', 'user', 'group'))) {
  369. throw new Exception("Niedozwolony typ odbiorcy");
  370. }
  371. if (empty($to) && 'everyone' != $toType) {
  372. throw new Exception("Proszę podać odbiorcę wiadomości");
  373. }
  374. if (empty($msg)) {
  375. throw new Exception("Proszę podać treść wiadomości");
  376. }
  377. }
  378. function _create($args, $tableName, $idRow) {
  379. $toType = V::get('to_type', '', $args);
  380. $to = V::get('to', '', $args);
  381. $msg = V::get('msg', '', $args);
  382. $usrLogin = User::getLogin();
  383. try {
  384. $createdId = DB::getPDO()->insert('CRM_UI_MSGS', [
  385. 'uiTargetType' => "default_db_table_record",
  386. 'uiTargetName' => "{$tableName}.{$idRow}",
  387. 'userTargetType' => $toType,
  388. 'userTargetName' => $to,
  389. 'msg' => $msg,
  390. 'A_RECORD_CREATE_DATE' => "NOW()",
  391. 'A_RECORD_CREATE_AUTHOR' => $usrLogin,
  392. 'A_STATUS' => "WAITING",
  393. 'app_className' => "TableMsgs",
  394. ]);
  395. } catch (Exception $e) {
  396. DBG::log($e);
  397. throw new Exception("Nie udało się zapisać wiadomości.");
  398. }
  399. return $createdId;
  400. }
  401. function _printMsgForm($args) {
  402. $toType = V::get('to_type', '', $args);
  403. $to = V::get('to', '', $args);
  404. $msg = V::get('msg', '', $args);
  405. $listTo = array();
  406. $listTo['everyone'] = 'Wszyscy';
  407. $listTo['user'] = 'Użytkownik';
  408. $listTo['group'] = 'Grupa';
  409. $toType = (array_key_exists($toType, $listTo))? $toType : 'everyone';
  410. $typeSpecialGroupId = TypespecialVariable::getInstance(-1, '__ZASOB');
  411. $typeSpecialUserLogin = TypespecialVariable::getInstance(-1, '__USER_LOGIN');
  412. $selectedLogin = ('user' == $toType)? $to : '';
  413. $selectedGroupId = ('group' == $toType)? $to : '';
  414. ?>
  415. <form class="form-horizontal" action="" method="post">
  416. <div class="form-group">
  417. <label class="col-sm-2 control-label" for="to">Do:</label>
  418. <div class="col-sm-3">
  419. <select name="to_type" class="form-control" onChange="return selectTblMsgsToType(this);">
  420. <?php foreach ($listTo as $type => $typeLabel) : ?>
  421. <option <?php echo ($type == $toType)? 'selected' : ''; ?>
  422. value="<?php echo $type; ?>"><?php echo $typeLabel; ?></option>
  423. <?php endforeach; ?>
  424. </select>
  425. </div>
  426. <div class="col-sm-7">
  427. <div id="tblMsgsTo-everyone" style="<?php echo ('everyone' == $toType)? '' : 'display:none'; ?>">
  428. <input name="to-everyone" type="text" class="form-control" disabled>
  429. </div>
  430. <div id="tblMsgsTo-group" style="<?php echo ('group' == $toType)? '' : 'display:none'; ?>">
  431. <?php if ($typeSpecialGroupId) : ?>
  432. <?php
  433. $fldName = 'to-group';
  434. $fldParams = array();
  435. $fldParams['allowCreate'] = false;
  436. $fldParams['ajaxDataUrlBase'] = "index.php?_route=TableMsgs&_task=typeSpecialGroupId";
  437. $fldParams['placeholder'] = 'Grupa...';
  438. //$fldParams['ajaxDataUrlBase'] .= "&DBG_TS=3";
  439. echo $typeSpecialUserLogin->showFormItem($tblID = -1, $fldName, $selectedGroupId, $fldParams);
  440. ?>
  441. <?php else : ?>
  442. <input name="to-group" type="text" class="form-control" placeholder="Grupa">
  443. <?php endif; ?>
  444. </div>
  445. <div id="tblMsgsTo-user" style="<?php echo ('user' == $toType)? '' : 'display:none'; ?>">
  446. <?php if ($typeSpecialUserLogin) : ?>
  447. <?php
  448. $fldName = 'to-user';
  449. $fldParams = array();
  450. $fldParams['allowCreate'] = false;
  451. $fldParams['ajaxDataUrlBase'] = "index.php?_route=TableMsgs&_task=typeSpecialUserLogin";
  452. $fldParams['placeholder'] = 'Użytkownik...';
  453. //$fldParams['ajaxDataUrlBase'] .= "&DBG_TS=3";
  454. echo $typeSpecialUserLogin->showFormItem($tblID = -1, $fldName, $selectedLogin, $fldParams);
  455. ?>
  456. <?php else : ?>
  457. <input name="to-user" type="text" class="form-control" placeholder="Użytkownik">
  458. <?php endif; ?>
  459. </div>
  460. </div>
  461. </div>
  462. <div class="form-group">
  463. <label for="to" class="col-sm-2 control-label">Wiadomość:</label>
  464. <div class="col-sm-10">
  465. <textarea name="msg" class="form-control"><?php echo htmlspecialchars($msg); ?></textarea>
  466. </div>
  467. </div>
  468. <div class="form-group">
  469. <div class="col-sm-10 col-sm-offset-2">
  470. <input class="btn btn-primary" type="submit" value="Wyślij">
  471. </div>
  472. </div>
  473. </form>
  474. <script>
  475. function selectTblMsgsToType(n) {
  476. var toTypes = <?php echo json_encode(array_keys($listTo)); ?>,
  477. selectedType = n.value
  478. ;
  479. if (-1 !== toTypes.indexOf(n.value)) {
  480. toTypes.forEach(function(type) {
  481. if (type == selectedType) {
  482. document.getElementById('tblMsgsTo-' + type).style.display = 'block';
  483. } else {
  484. document.getElementById('tblMsgsTo-' + type).style.display = 'none';
  485. }
  486. });
  487. }
  488. }
  489. </script>
  490. <?php
  491. }
  492. function typeSpecialUserLoginAction() {
  493. header("Content-type: application/json");
  494. $typeSpecialUserId = TypespecialVariable::getInstance(-1, '__USER_LOGIN');
  495. if (!$typeSpecialUserId) {
  496. $jsonData = new stdClass();
  497. $jsonData->message = "TypeSpecial '__USER_LOGIN' not exists";
  498. echo json_encode($jsonData);
  499. exit;
  500. }
  501. $query = V::get('q', '', $_REQUEST);
  502. $rawRows = null;
  503. $jsonData = array();
  504. $queryParams = array();
  505. $rows = $typeSpecialUserId->getValuesWithExports($query, $queryParams);
  506. foreach ($rows as $kID => $vItem) {
  507. $itemJson = new stdClass();
  508. $itemJson->id = $vItem->id;
  509. $itemJson->name = $vItem->param_out;
  510. if (!empty($vItem->exports)) {
  511. $itemJson->exports = $vItem->exports;
  512. }
  513. $jsonData[] = $itemJson;
  514. }
  515. echo json_encode($jsonData);
  516. }
  517. function typeSpecialGroupIdAction() {
  518. header("Content-type: application/json");
  519. Lib::loadClass('TypespecialVariable');
  520. $typeSpecialZasob = TypespecialVariable::getInstance(-1, '__ZASOB');
  521. if (!$typeSpecialZasob) {
  522. $jsonData = new stdClass();
  523. $jsonData->message = "TypeSpecial '__ZASOB' not exists";
  524. echo json_encode($jsonData);
  525. exit;
  526. }
  527. $query = V::get('q', '', $_REQUEST);
  528. $rawRows = null;
  529. $jsonData = array();
  530. $queryParams = array();
  531. $queryParams['zasob_type_in'] = array('STANOWISKO', 'PODMIOT', 'DZIAL');
  532. $rows = $typeSpecialZasob->getValuesWithExports($query, $queryParams);
  533. DBG::_('DBG_TS', '>1', "rows({$query})", $rows, __CLASS__, __FUNCTION__, __LINE__);
  534. foreach ($rows as $kID => $vItem) {
  535. $itemJson = new stdClass();
  536. $itemJson->id = $vItem->id;
  537. $itemJson->name = $vItem->param_out;
  538. if (!empty($vItem->exports)) {
  539. $itemJson->exports = $vItem->exports;
  540. }
  541. $jsonData[] = $itemJson;
  542. }
  543. echo json_encode($jsonData);
  544. }
  545. function readAction() {
  546. $idMsg = V::get('id', 0, $_GET, 'int');
  547. $usrLogin = V::get('usrLogin', '', $_REQUEST, 'word');
  548. if ($idMsg <= 0) throw new HttpException("Wiadomość nie istnieje!", 404);
  549. if (empty($usrLogin)) throw new HttpException("Błęny user login!", 404);
  550. UI::gora();
  551. UI::menu();
  552. try {
  553. $msg = $this->_getMsg($idMsg, $usrLogin);
  554. $this->_markAsRead($msg);
  555. $this->viewMsg($msg);
  556. } catch (Exception $e) {
  557. UI::alert('danger', $e->getMessage() . ' #' . $e->getLine());
  558. }
  559. UI::dol();
  560. }
  561. function viewAction() {
  562. $idMsg = V::get('id', 0, $_GET, 'int');
  563. $usrLogin = V::get('usrLogin', 0, $_REQUEST, 'word');
  564. if ($idMsg <= 0) throw new HttpException("Wiadomość nie istnieje!", 404);
  565. if (empty($usrLogin)) throw new HttpException("Błęny user login", 404);
  566. UI::gora();
  567. UI::menu();
  568. try {
  569. $msg = $this->_getMsg($idMsg, $usrLogin);
  570. $this->viewMsg($msg);
  571. } catch (Exception $e) {
  572. UI::alert('danger', $e->getMessage() . ' #' . $e->getLine());
  573. }
  574. UI::dol();
  575. }
  576. function _getMsg($idMsg, $usrLogin) {
  577. $msgsRoute = Router::getRoute('Msgs');
  578. $msg['_raw'] = $msgsRoute->getMessage($idMsg);
  579. if (!$msg['_raw']) throw new HttpException("Wiadomość nie istnieje!", 404);
  580. $msg['usrLogin'] = $usrLogin;
  581. $msg['message'] = $msg['_raw']->msg;
  582. $msg['type'] = $msg['_raw']->msgType;
  583. $msg['_read'] = ('WAITING' != $msg['_raw']->A_STATUS);
  584. // `uiTargetType` enum('default_db_table','default_db_table_record','after_login','everywhere') NOT NULL, // TODO: add namespace, featureID
  585. // $msg['_raw']->uiTargetType => default_db_table_record
  586. // $msg['_raw']->uiTargetName => TEST_PERMS.31
  587. if ('default_db_table_record' !== $msg['_raw']->uiTargetType) {
  588. throw new Exception("Parse message target type error!");
  589. }
  590. $parts = explode('.', $msg['_raw']->uiTargetName);
  591. if (2 !== count($parts)) throw new Exception("Parse message target type error!");
  592. $msg['tblName'] = $parts[0];
  593. $msg['idRow'] = $parts[1];
  594. if (!is_numeric($msg['idRow'])) throw new Exception("Parse message target type - id row type error!");
  595. return $msg;
  596. }
  597. function _markAsRead($msg) {
  598. if ($msg['_read']) return;
  599. $usrLogin = User::getLogin();
  600. $sql = "
  601. update `CRM_UI_MSGS`
  602. set `A_STATUS` = 'NORMAL'
  603. , `A_RECORD_UPDATE_AUTHOR` = '{$usrLogin}'
  604. , `A_RECORD_UPDATE_DATE` = NOW()
  605. , `actionExecutedTime` = NOW()
  606. where `ID`='{$msg['_raw']->ID}'
  607. and `A_STATUS` = 'WAITING'
  608. and `A_RECORD_UPDATE_AUTHOR` = ''
  609. and `A_RECORD_UPDATE_DATE` is null
  610. and (
  611. ('{$usrLogin}' != `A_RECORD_CREATE_AUTHOR`)
  612. or ('{$usrLogin}' = `A_RECORD_CREATE_AUTHOR`
  613. and 'user' = `userTargetType`
  614. and '{$usrLogin}' = `userTargetName`
  615. )
  616. )
  617. ";
  618. try {
  619. DB::getPDO()->execSql($sql);
  620. } catch (Exception $e) {
  621. DBG::log($e);
  622. throw new Exception("Wystąpiły błędy podczas próby zapisu wiadomości: " . $e->getMessage());
  623. }
  624. }
  625. function viewMsg($msg) {
  626. $usrLogin = User::getLogin();
  627. $idTable = 0;
  628. //$rmMsgLink = "{$linkBase}&_task=removeMsg&id={$msg['_raw']->ID}";
  629. $targetNamespace = (!empty($msg['tblName'])) ? "default_db/{$msg['tblName']}" : ""; // default_db/CRM_LISTA_ZASOBOW
  630. $idRow = (!empty($msg['idRow'])) ? $msg['idRow'] : "";
  631. $targetLabel = ($targetNamespace) ? $this->getOutTargetLabel($targetNamespace) : ""; // $tblAcl->getRawLabel()
  632. echo UI::h('div', [ 'class' => "container" ], [
  633. UI::h('h3', [], [
  634. UI::h('i', [ 'class' => "glyphicon glyphicon-envelope" ]),
  635. " ",
  636. UI::h('a', [ 'href' => $this->getLink('', [ 'usrLogin' => $usrLogin ]) ], "Wiadomości {$usrLogin}"),
  637. " &raquo; ",
  638. " Wiadomość nr {$msg['_raw']->ID}",
  639. ($targetNamespace && $idRow)
  640. ? UI::h('small', [ 'style' => "display:block; text-align:right" ], [
  641. UI::h('a', [
  642. 'style' => "font-size:12px; line-height:15px; vertical-align:text-bottom",
  643. 'title' => "Edytuj rekord",
  644. 'href' => "index.php?_route=ViewTableAjax&namespace={$targetNamespace}#EDIT/{$idRow}",
  645. ], [
  646. UI::h('i', [ 'class' => "glyphicon glyphicon-pencil" ]),
  647. " Edytuj rekord {$idRow}",
  648. ]),
  649. UI::h('span', [ 'style' => "font-size:12px; line-height:15px; vertical-align:text-bottom" ], " z tabeli "),
  650. UI::h('a', [
  651. 'style' => "font-size:12px; line-height:15px; vertical-align:text-bottom",
  652. 'href' => "index.php?_route=ViewTableAjax&namespace={$targetNamespace}",
  653. ], $targetLabel),
  654. " ",
  655. $this->printMsgDropdownMenu($msg['_raw']),
  656. ])
  657. : ''
  658. ,
  659. ]),
  660. ]);
  661. $this->printWidgetViewMsg($msg);
  662. }
  663. function getOutTargetLabel($ns) {
  664. try {
  665. $acl = ACL::getAclByNamespace($ns);
  666. return $acl->getRawLabel();
  667. } catch (Exception $e) {
  668. DBG::log($e);
  669. }
  670. return $ns;
  671. }
  672. function printMsgDropdownMenu($rawMsg) {
  673. $isRemoved = ('DELETED' === $rawMsg->A_STATUS || 'OFF_HARD' == $rawMsg->A_STATUS);
  674. return UI::h('div', [ 'class' => "dropdown", 'style' => "display:inline" ], [
  675. UI::h('button', [ 'class' => "btn btn-xs btn-default dropdown-toggle", 'title' => "Message Menu", 'data-toggle' => "dropdown" ], [
  676. UI::h('i', [ 'class' => "glyphicon glyphicon-menu-hamburger" ]),
  677. " Menu",
  678. ]),
  679. UI::h('ul', [ 'class' => "dropdown-menu dropdown-menu-right" ], [
  680. UI::h('li', [], [
  681. ($isRemoved)
  682. ? UI::h('form', [ 'method' => "POST" ], [
  683. UI::h('input', [ 'type' => 'hidden', 'name' => "_postTask", 'value' => "restoreMsg" ]),
  684. UI::h('input', [ 'type' => 'hidden', 'name' => "id", 'value' => $rawMsg->ID ]),
  685. UI::h('button', [ 'type' => "submit", 'class' => "btn btn-link" ], [
  686. UI::h('i', [ 'class' => "glyphicon glyphicon-inbox" ]),
  687. " Przywróć",
  688. ]),
  689. ])
  690. : UI::h('form', [ 'method' => "POST" ], [
  691. UI::h('input', [ 'type' => 'hidden', 'name' => "_postTask", 'value' => "removeMsg" ]),
  692. UI::h('input', [ 'type' => 'hidden', 'name' => "id", 'value' => $rawMsg->ID ]),
  693. UI::h('button', [ 'type' => "submit", 'class' => "btn btn-link", 'style' => "color:red" ], [
  694. UI::h('i', [ 'class' => "glyphicon glyphicon-remove" ]),
  695. " Usuń"
  696. ]),
  697. ])
  698. ,
  699. ]),
  700. ]),
  701. ]);
  702. }
  703. function printWidgetViewMsg($msg) {
  704. $uiTargetName = $msg['_raw']->uiTargetName;
  705. $uiTargetType = $msg['_raw']->uiTargetType;
  706. $replyLink = "index.php?_route=UserMsgs&_task=reply&uiTargetName={$uiTargetName}&uiTargetType={$uiTargetType}";
  707. $markAsReadLink = "index.php?_route=UserMsgs&_task=markAsRead";
  708. $message = $this->_convertMessageToJson($msg['_raw']);
  709. {//if ($message->idThread > 0) {
  710. $sqlLimit = 100;
  711. $sqlIdThread = ($message->idThread > 0)? $message->idThread : $message->id;
  712. $messageList = array_map(function ($msg) {
  713. return $this->_convertMessageToJson((object)$msg);
  714. }, DB::getPDO()->fetchAll("
  715. select m.*
  716. from CRM_UI_MSGS m
  717. where ( m.idThread = :id_thread or m.ID = :id_thread )
  718. order by m.ID asc
  719. limit {$sqlLimit}
  720. ", [
  721. ':id_thread' => $sqlIdThread
  722. ]));
  723. // -- and m.`ID` < {$message->id}
  724. }
  725. ?>
  726. <link rel="stylesheet" href="./stuff/widget-select.css">
  727. <style type="text/css">
  728. .user_avatar {
  729. display:block;
  730. width:40px;
  731. height:40px;
  732. margin:0 auto 10px auto;
  733. padding:0;
  734. border:1px solid #ddd;
  735. line-height: 38px;
  736. font-size:16px;
  737. text-align:center;
  738. vertical-align:middle;
  739. color:#aaa;
  740. }
  741. </style>
  742. <div id="widget-msg-tree" style="max-width:1000px; margin:0 auto;"></div>
  743. <script src="stuff/vendors.js"></script>
  744. <script src="stuff/bundle.se_route_user_msgs.js"></script>
  745. <script>
  746. var testNewRecordCounter = 0;
  747. jQuery("#widget-msg-tree").MsgThread({
  748. usrLogin: '<?php echo User::getLogin(); ?>',
  749. idThread: <?php echo $message->idThread; ?>,
  750. msgs: <?php echo json_encode($messageList); ?>,
  751. fetchMessages: (function() {
  752. var _msgsXhr = null;
  753. return function(reqData, callback) {
  754. if (_msgsXhr && _msgsXhr.state() === 'pending') {
  755. _msgsXhr.abort();
  756. _msgsXhr = null;
  757. }
  758. _msgsXhr = $.ajax({
  759. url: 'index.php?_route=UserMsgs&_task=getMessagesById&idThread=<?php echo $message->idThread; ?>',
  760. data: reqData,
  761. dataType: 'json'
  762. });
  763. _msgsXhr.done(function(data, textStatus, jqXHR) {
  764. if (data && data.msgs && data.msgs.length > 0) {
  765. callback(null, {msgs: data.msgs});
  766. } else {
  767. callback(null, {msgs: []});//"Error no data!");
  768. }
  769. });
  770. _msgsXhr.fail(function() {
  771. callback(null, {options: []});//"Error no data!");
  772. });
  773. _msgsXhr.always(function() {
  774. _msgsXhr = null;
  775. });
  776. };
  777. })(),
  778. fetchOptionsForGroup: (function() {
  779. var _groupXhr = null;
  780. return function(input, callback) {
  781. if (_groupXhr && _groupXhr.state() === 'pending') {
  782. _groupXhr.abort();
  783. _groupXhr = null;
  784. }
  785. _groupXhr = $.ajax({
  786. url: 'index.php?_route=UserMsgs&_task=typeSpecialGroupId&q=' + input,
  787. dataType: 'json'
  788. });
  789. _groupXhr.done(function(data, textStatus, jqXHR) {
  790. if (data && data.length > 0) {
  791. var options = [];
  792. data.forEach(function(item) {
  793. options.push({value: item.id, label: item.name});
  794. });
  795. callback(null, {options: options});
  796. } else {
  797. callback(null, {options: []});//"Error no data!");
  798. }
  799. });
  800. _groupXhr.fail(function() {
  801. callback(null, {options: []});//"Error no data!");
  802. });
  803. _groupXhr.always(function() {
  804. _groupXhr = null;
  805. });
  806. };
  807. })(),
  808. fetchOptionsForUser: (function() {
  809. var _userXhr = null;
  810. return function(input, callback) {
  811. if (_userXhr && _userXhr.state() === 'pending') {
  812. _userXhr.abort();
  813. _userXhr = null;
  814. }
  815. _userXhr = $.ajax({
  816. url: 'index.php?_route=UserMsgs&_task=typeSpecialUserLogin&q=' + input,
  817. dataType: 'json'
  818. });
  819. _userXhr.done(function(data, textStatus, jqXHR) {
  820. if (data && data.length > 0) {
  821. var options = [];
  822. data.forEach(function(item) {
  823. options.push({value: item.id, label: item.name});
  824. });
  825. callback(null, {options: options});
  826. } else {
  827. callback(null, {options: []});//"Error no data!");
  828. }
  829. });
  830. _userXhr.fail(function() {
  831. callback(null, {options: []});//"Error no data!");
  832. });
  833. _userXhr.always(function() {
  834. _userXhr = null;
  835. });
  836. };
  837. })(),
  838. saveReply: function(data, callback) {
  839. //console.log('#widget-msg-tree/MsgThread::saveReply: data:', data, 'callback', callback);
  840. $.ajax({
  841. url: '<?php echo $replyLink; ?>',
  842. method: 'POST',
  843. data: data,
  844. dataType: 'json'
  845. })
  846. .done(function(data, textStatus, jqXHR) {
  847. var returnData = {message: '', type: 'danger'};
  848. if (data && data.record) {
  849. returnData.msg = data.msg || 'Wysłano wiadomość';
  850. returnData.record = data.record;
  851. returnData.type = 'success';
  852. } else if (data.validateErrors) {
  853. returnData.msg = data.msg || 'Wystąpiły błędy w formularzu';
  854. returnData.type = 'warning';
  855. returnData.validateErrors = data.validateErrors;
  856. } else {
  857. returnData.msg = data.msg || 'Nie udało się wysłać wiadomości!';
  858. returnData.type = 'danger';
  859. }
  860. callback(null, returnData);
  861. })
  862. .fail(function() {
  863. callback(null, {message: 'Nie udało się wysłać wiadomości!', type: 'danger'});
  864. });
  865. },
  866. markAsRead: function(idMsg, callback) {
  867. //console.log('#widget-msg-tree/MsgThread::markAsRead: idMsg:', idMsg);
  868. $.ajax({
  869. url: '<?php echo $markAsReadLink; ?>&idMsg=' + idMsg,
  870. method: 'GET',
  871. dataType: 'json'
  872. })
  873. .done(function(data, textStatus, jqXHR) {
  874. var returnData = {message: '', type: 'danger'};
  875. if (data && data.record) {
  876. returnData.msg = data.msg || 'Oznaczono wiadomość jako odczytaną';
  877. returnData.record = data.record;
  878. returnData.type = 'success';
  879. } else {
  880. returnData.msg = data.msg || 'Nie udało się oznaczyć wiadomości jako odczytanej!';
  881. returnData.type = 'danger';
  882. }
  883. callback(null, returnData);
  884. })
  885. .fail(function() {
  886. callback(null, {message: 'Nie udało się oznaczyć wiadomości jako odczytanej!', type: 'danger'});
  887. });
  888. },
  889. dbg: false
  890. });
  891. // jQuery("#widget-msg-tree").on('change', function(e, data) {
  892. // console.log('#widget-msg-tree/MsgThread::onChange: data:', data);
  893. // });
  894. </script>
  895. <?php
  896. }
  897. function _convertMessageToJson($rawMsg) {
  898. /* $msg = {_raw: {A_RECORD_CREATE_AUTHOR: "plabudda",
  899. A_RECORD_CREATE_DATE: "2015-10-26 12:20:05",
  900. A_RECORD_DELETE_AUTHOR: "",
  901. A_RECORD_DELETE_DATE: null,
  902. A_RECORD_UPDATE_AUTHOR: "plabudda",
  903. A_RECORD_UPDATE_DATE: "2015-11-02 12:44:59",
  904. A_STATUS: "NORMAL",
  905. ID: "67",
  906. actionExecutedTime: "2015-11-02 12:44:59",
  907. actionNotes: "",
  908. app_className: "TableMsgs",
  909. msg: "test Y",
  910. msgType: "info",
  911. uiTargetName: "TEST_PERMS.31",
  912. uiTargetType: "default_db_table_record",
  913. userTargetName: "plabudda",
  914. userTargetType: "user"}
  915. _read: true,
  916. idRow: "31",
  917. message: "test Y",
  918. tblName: "TEST_PERMS",
  919. type: "info",
  920. usrLogin: "plabudda"} */
  921. $usrLogin = User::getLogin();
  922. $message = new stdClass();
  923. $message->id = $rawMsg->ID;
  924. $message->idThread = $rawMsg->idThread;// TODO: ID_THREAD
  925. $message->idReplyTo = $rawMsg->idReplyTo;// TODO: ID_REPLY_TO
  926. $message->message = $rawMsg->msg;
  927. $message->type = $rawMsg->msgType;
  928. $message->to = $rawMsg->userTargetName;
  929. $message->toType = $rawMsg->userTargetType;
  930. $message->author = $rawMsg->A_RECORD_CREATE_AUTHOR;
  931. $message->created = $rawMsg->A_RECORD_CREATE_DATE;
  932. $message->_read = ('WAITING' != $rawMsg->A_STATUS);
  933. $message->_readByUser = ('WAITING' != $rawMsg->A_STATUS);
  934. if ('WAITING' == $rawMsg->A_STATUS
  935. && $usrLogin == $rawMsg->A_RECORD_CREATE_AUTHOR) {
  936. if ('user' == $rawMsg->userTargetType
  937. && $usrLogin == $rawMsg->userTargetName) {
  938. $message->_readByUser = false;
  939. } else {
  940. $message->_readByUser = true;
  941. }
  942. }
  943. if ($message->_read) {
  944. if (!empty($rawMsg->A_RECORD_UPDATE_DATE)) $message->_readDate = $rawMsg->A_RECORD_UPDATE_DATE;
  945. if (!empty($rawMsg->A_RECORD_UPDATE_AUTHOR)) $message->_readBy = $rawMsg->A_RECORD_UPDATE_AUTHOR;
  946. }
  947. return $message;
  948. }
  949. function getMessagesByIdAction() {
  950. try {
  951. $idThread = V::get('idThread', '', $_GET, 'int');
  952. $idLastMsg = V::get('idLastMsg', '', $_GET, 'int');
  953. if ($idThread <= 0) throw new Exception("Wrong param id!");
  954. $sqlLimit = 10;// TODO: 100?
  955. $moreMsgs = array_map(function ($item) {
  956. return (object)$item;
  957. }, DB::getPDO()->fetchAll("
  958. select m.*
  959. from CRM_UI_MSGS m
  960. where m.idThread = :id_thread
  961. and m.ID > :id_last_msg
  962. order by m.ID asc
  963. limit {$sqlLimit}
  964. ", [
  965. ':id_thread' => $idThread,
  966. ':id_last_msg' => $idLastMsg,
  967. ]));
  968. $response = new stdClass();
  969. $response->msg = "Nowe wiadomości";
  970. $response->type = 'success';
  971. $response->msgs = array();
  972. foreach ($moreMsgs as $msg) {
  973. $response->msgs[] = $this->_convertMessageToJson($msg);
  974. }
  975. } catch (Exception $e) {
  976. $response = new stdClass();
  977. $response->msg = "Wystąpiły błędy: " . $e->getMessage();
  978. $response->type = 'danger';
  979. }
  980. echo json_encode($response);
  981. }
  982. function replyAction() {
  983. try {
  984. $uiTargetType = V::get('uiTargetType', '', $_GET);
  985. $uiTargetName = V::get('uiTargetName', '', $_GET);
  986. $response = $this->_reply($uiTargetType, $uiTargetName, $_POST);
  987. } catch (Exception $e) {
  988. $response = new stdClass();
  989. $response->msg = "Wystąpiły błędy: " . $e->getMessage();
  990. $response->type = 'danger';
  991. }
  992. echo json_encode($response);
  993. }
  994. function markAsReadAction() {
  995. $usrLogin = User::getLogin();
  996. try {
  997. $idMsg = V::get('idMsg', '', $_GET, 'int');
  998. $msg = $this->_getMsg($idMsg, $usrLogin);
  999. $this->_markAsRead($msg);
  1000. $response = new stdClass();
  1001. //$response->msg = "";
  1002. $response->type = "success";
  1003. $msg = $this->_getMsg($idMsg, $usrLogin);
  1004. $response->record = $this->_convertMessageToJson($msg['_raw']);
  1005. } catch (Exception $e) {
  1006. $response = new stdClass();
  1007. $response->msg = "Wystąpiły błędy: " . $e->getMessage();
  1008. $response->type = 'danger';
  1009. }
  1010. echo json_encode($response);
  1011. }
  1012. function _reply($uiTargetType, $uiTargetName, $args) {
  1013. $newMsg = array();
  1014. $newMsg['idReplyTo'] = V::get('idReplyTo', '', $args, 'int');
  1015. $newMsg['msg'] = V::get('message', '', $args);
  1016. $newMsg['msgType'] = V::get('msgType', 'info', $args);
  1017. $newMsg['userTargetType'] = V::get('toType', '', $args);
  1018. $newMsg['userTargetName'] = V::get('to', '', $args);
  1019. $newMsg['A_RECORD_CREATE_DATE'] = 'NOW()';
  1020. $newMsg['A_RECORD_CREATE_AUTHOR'] = User::getLogin();
  1021. $newMsg['app_className'] = 'TableMsgs';
  1022. //DBG::_(true, true, "newMsg", $newMsg, __CLASS__, __FUNCTION__, __LINE__);
  1023. if ($newMsg['idReplyTo'] <= 0) throw new Exception("Wrong id reply to msg");
  1024. $parentMsg = DB::getPDO()->fetchFirst(" select * from CRM_UI_MSGS where ID = :id ", [ ':id' => $newMsg['idReplyTo'] ]);
  1025. if (!$parentMsg) throw new Exception("Nie znaleziono wiadomości");
  1026. $parentMsg = (object)$parentMsg;
  1027. $newMsg['idThread'] = ($parentMsg->idThread > 0)? $parentMsg->idThread : $parentMsg->ID;
  1028. $newMsg['uiTargetType'] = $uiTargetType;// TODO:? $parentMsg->uiTargetType
  1029. $newMsg['uiTargetName'] = $uiTargetName;// TODO:? $parentMsg->uiTargetName
  1030. $insertedId = DB::getPDO()->insert('CRM_UI_MSGS', $newMsg);
  1031. if (!$insertedId) throw new Exception("Nie udało się utworzyć rekordu");
  1032. $msgAdded = DB::getPDO()->fetchFirst(" select * from CRM_UI_MSGS where ID = :id ", [ ':id' => $insertedId ]);
  1033. if (!$msgAdded) throw new Exception("Nie naleziono rekordu nr '{$insertedId}'");
  1034. $msgAdded = (object)$msgAdded;
  1035. $response = new stdClass();
  1036. $response->msg = "Wysłano wiadomość";
  1037. $response->type = 'success';
  1038. $response->record = $this->_convertMessageToJson($msgAdded);
  1039. return $response;
  1040. }
  1041. function removeMsgAction() {
  1042. $idMsg = V::get('id', 0, $_GET, 'int');
  1043. $usrLogin = V::get('usrLogin', 0, $_REQUEST, 'word');
  1044. if ($idMsg <= 0) throw new HttpException("Wiadomość nie istnieje!", 404);
  1045. if (empty($usrLogin)) throw new HttpException("Błęny user login", 404);
  1046. UI::gora();
  1047. UI::menu();
  1048. try {
  1049. $msg = $this->_getMsg($idMsg, $usrLogin);
  1050. $msgsRoute = Router::getRoute('Msgs');
  1051. $msgsRoute->removeTableRecordMsg($idMsg);
  1052. } catch (Exception $e) {
  1053. UI::alert('danger', $e->getMessage() . ' #' . $e->getLine());
  1054. UI::dol();
  1055. exit;
  1056. }
  1057. ?>
  1058. <div class="container">
  1059. <div class="alert alert-success">
  1060. Wiadomość została usunięta <a class="btn btn-xs btn-default" href="index.php?_route=UserMsgs&usrLogin=<?php echo $usrLogin; ?>">wróć</a>
  1061. </div>
  1062. </div>
  1063. <?php
  1064. UI::dol();
  1065. }
  1066. function removeMsgPostTask($args) {
  1067. try {
  1068. $id = V::get('id', 0, $args, 'int');
  1069. if ($id <= 0) throw new AlertDangerException("Missing message id!");
  1070. $usrLogin = V::get('usrLogin', User::getLogin(), $_REQUEST, 'word');
  1071. $msg = $this->_getMsg($id, $usrLogin);
  1072. $isRemoved = ('DELETED' === $msg['_raw']->A_STATUS || 'OFF_HARD' == $msg['_raw']->A_STATUS);
  1073. if ($isRemoved) throw new AlertInfoException("Wiadomość nr {$id} została usunięta wcześniej");
  1074. Router::getRoute('Msgs')->removeTableRecordMsg($id);
  1075. throw new AlertInfoException("Usunięto wiadomość nr {$id}"); // TODO: przywróć btn require global post task class
  1076. } catch (Exception $e) {
  1077. DBG::log($e);
  1078. S::saveUserMessage(get_class($e), $e->getMessage());
  1079. }
  1080. }
  1081. function restoreMsgPostTask($args) {
  1082. try {
  1083. $id = V::get('id', 0, $args, 'int');
  1084. if ($id <= 0) throw new AlertDangerException("Missing message id!");
  1085. $usrLogin = V::get('usrLogin', User::getLogin(), $_REQUEST, 'word');
  1086. $msg = $this->_getMsg($id, $usrLogin);
  1087. $isRemoved = ('DELETED' === $msg['_raw']->A_STATUS || 'OFF_HARD' == $msg['_raw']->A_STATUS);
  1088. if (!$isRemoved) throw new AlertInfoException("Wiadomość nr {$id} nie jest usunięta");
  1089. Router::getRoute('Msgs')->restoreTableRecordMsg($id);
  1090. throw new AlertInfoException("Przywrócono wiadomość nr {$id}"); // TODO: przywróć btn require global post task class
  1091. } catch (Exception $e) {
  1092. DBG::log($e);
  1093. S::saveUserMessage(get_class($e), $e->getMessage());
  1094. }
  1095. }
  1096. }