Msgs.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479
  1. <?php
  2. Lib::loadClass('RouteBase');
  3. /*
  4. ## Flash message system:
  5. System for automatic and custom messages for users.
  6. - `app_className` - for automatic msgs to search for msg text
  7. - `msg` - msg to show or to parse by `app_className`
  8. - `uiTargetType` - where to show this msg eg. 'default_db_table', 'after_login', 'everywhere'
  9. - `uiTargetName` - eg. database table name (if from default_db)
  10. - `userTargetType` - type of users allowed to see this msg eg. 'everyone', 'admin' (ADMIN_LEVEL=0?), 'user', 'group'
  11. - `userTargetName` - login, group name
  12. - `actionExecuted` - execution time if msg require user to run specific action (send msg.id in request)
  13. - `actionNotes` - notes/msgs/dbg for user actions executed from this msg
  14. Messages created by db triggers must define `app_className` that should parse `msg`. For example to use in FixProjectPath and FixZasobPath to keep correct paths.
  15. */
  16. class Route_Msgs extends RouteBase {
  17. public function handleAuth() {
  18. if (!User::logged()) {
  19. throw new HttpException('Unauthorized', 401);
  20. }
  21. }
  22. public function defaultAction() {
  23. SE_Layout::gora();
  24. ?>
  25. <div class="container">
  26. <h1>Messages system</h1>
  27. ...
  28. </div>
  29. <?php
  30. SE_Layout::dol();
  31. }
  32. public function reinstallAction() {
  33. $this->reinstall();
  34. die('OK');
  35. }
  36. public function reinstallFunctionsAction() {
  37. $this->reinstallFunctions();
  38. die('OK');
  39. }
  40. public function runAction() {
  41. $msgId = V::get('_msgId', 0, $_REQUEST, 'int');
  42. if ($msgId > 0) {
  43. $this->runByMessageId($msgId);
  44. }
  45. $jsonData = new stdClass();
  46. $jsonData->type = 'success';
  47. $jsonData->msg = 'Gotowe';
  48. echo json_encode($jsonData);
  49. exit;
  50. }
  51. public function addTestMsgAction() {
  52. $sql = "INSERT INTO `CRM_UI_MSGS` (`ID`, `app_className`, `msg`, `msgType`, `uiTargetType`, `uiTargetName`, `userTargetType`, `userTargetName`, `actionExecutedTime`, `actionNotes`, `A_RECORD_CREATE_DATE`, `A_RECORD_CREATE_AUTHOR`, `A_RECORD_UPDATE_DATE`, `A_RECORD_UPDATE_AUTHOR`)
  53. VALUES (NULL, 'FixZasobPath', 'Update all paths', 'danger', 'default_db_table', 'CRM_LISTA_ZASOBOW', 'user', 'plabudda', NULL, '', NULL, 'plabudda', NULL, '')";
  54. $db = DB::getDB();
  55. $db->query($sql);
  56. die('OK');
  57. }
  58. public function reinstallFunctions() {
  59. $sqlList = array();
  60. $sqlList['RemoveProcedureMarkAsExecuted'] = "DROP PROCEDURE IF EXISTS `CRM_UI_MSGS__markAsExecuted`";
  61. $sqlList['InstallProcedureMarkAsExecuted'] = <<<SQL_QUERY
  62. CREATE DEFINER=`root`@`localhost` PROCEDURE `CRM_UI_MSGS__markAsExecuted`(
  63. IN author VARCHAR(40),
  64. IN app_className VARCHAR(255),
  65. IN msg VARCHAR(255),
  66. IN uiTargetType VARCHAR(255),
  67. IN uiTargetName VARCHAR(255),
  68. IN userTargetType VARCHAR(255),
  69. IN userTargetName VARCHAR(255)
  70. )
  71. BEGIN
  72. update `CRM_UI_MSGS`
  73. set `A_STATUS`='OFF_HARD'
  74. , `actionExecutedTime`=NOW()
  75. , `A_RECORD_UPDATE_DATE`=NOW()
  76. , `A_RECORD_UPDATE_AUTHOR`=author
  77. where `A_STATUS`='WAITING' -- TODO: not in('DELETED', 'OFF_HARD')
  78. and `app_className`=app_className
  79. and `msg`=msg
  80. and `uiTargetType`=uiTargetType
  81. and `uiTargetName`=uiTargetName
  82. and `userTargetType`=userTargetType
  83. and `userTargetName`=userTargetName
  84. ;
  85. END
  86. SQL_QUERY;
  87. $sqlList['RemoveProcedureMarkTableEveryoneAsExecuted'] = "DROP PROCEDURE IF EXISTS `CRM_UI_MSGS__markTableEveryoneAsExecuted`";
  88. $sqlList['InstallProcedureMarkTableEveryoneAsExecuted'] = <<<SQL_QUERY
  89. CREATE DEFINER=`root`@`localhost` PROCEDURE `CRM_UI_MSGS__markTableEveryoneAsExecuted`(
  90. IN author VARCHAR(40),
  91. IN app_className VARCHAR(255),
  92. IN msg VARCHAR(255),
  93. IN uiTargetName VARCHAR(255)
  94. )
  95. BEGIN
  96. CALL CRM_UI_MSGS__markAsExecuted(author, app_className, msg, 'default_db_table', uiTargetName, 'everyone', '');
  97. END
  98. SQL_QUERY;
  99. $sqlList['RemoveProcedureAddUniqueMsg'] = "DROP PROCEDURE IF EXISTS `CRM_UI_MSGS__addUniqueMsg`";
  100. $sqlList['InstallProcedureAddUniqueMsg'] = <<<SQL_QUERY
  101. CREATE DEFINER=`root`@`localhost` PROCEDURE `CRM_UI_MSGS__addUniqueMsg`(
  102. IN author VARCHAR(40),
  103. IN app_className VARCHAR(255),
  104. IN msgType VARCHAR(16),
  105. IN msg VARCHAR(255),
  106. IN uiTargetType VARCHAR(255),
  107. IN uiTargetName VARCHAR(255),
  108. IN userTargetType VARCHAR(255),
  109. IN userTargetName VARCHAR(255)
  110. )
  111. BEGIN
  112. IF (select count(1)
  113. from `CRM_UI_MSGS`
  114. where `app_className`=app_className
  115. and `msg`=msg
  116. and `uiTargetType`=uiTargetType
  117. and `uiTargetName`=uiTargetName
  118. and `userTargetType`=userTargetType
  119. and `userTargetName`=userTargetName
  120. and `A_STATUS`='WAITING'
  121. ) = 0 THEN
  122. INSERT INTO `CRM_UI_MSGS` (`ID`
  123. , `app_className`, `msg`, `msgType`
  124. , `uiTargetType`, `uiTargetName`
  125. , `userTargetType`, `userTargetName`
  126. , `A_RECORD_CREATE_DATE`, `A_RECORD_CREATE_AUTHOR`)
  127. VALUES (NULL
  128. , app_className, msg, msgType
  129. , uiTargetType, uiTargetName
  130. , userTargetType, userTargetName
  131. , NOW(), author
  132. );
  133. END IF;
  134. END
  135. SQL_QUERY;
  136. $sqlList['RemoveProcedureAddTableEveryoneUniqueMsg'] = "DROP PROCEDURE IF EXISTS `CRM_UI_MSGS__addTableEveryoneUniqueMsg`";
  137. $sqlList['InstallProcedureAddTableEveryoneUniqueMsg'] = <<<SQL_QUERY
  138. CREATE DEFINER=`root`@`localhost` PROCEDURE `CRM_UI_MSGS__addTableEveryoneUniqueMsg`(
  139. IN author VARCHAR(40),
  140. IN app_className VARCHAR(255),
  141. IN msgType VARCHAR(16),
  142. IN msg VARCHAR(255),
  143. IN uiTargetName VARCHAR(255)
  144. )
  145. BEGIN
  146. CALL CRM_UI_MSGS__addUniqueMsg(author, app_className, msgType, msg, 'default_db_table', uiTargetName, 'everyone', '');
  147. END
  148. SQL_QUERY;
  149. $formFixZasobPath = <<<SQL_QUERY
  150. CALL CRM_UI_MSGS__addTableEveryoneUniqueMsg(NEW.A_RECORD_UPDATE_AUTHOR, 'FixZasobPath', 'danger', 'Update all paths', 'CRM_LISTA_ZASOBOW');
  151. IF (select count(1) from `CRM_UI_MSGS` where `app_className`='FixZasobPath'
  152. and `msg`='Update all paths'
  153. and `uiTargetType`='default_db_table'
  154. and `uiTargetName`='CRM_LISTA_ZASOBOW'
  155. and `A_STATUS`='WAITING'
  156. ) = 0 THEN
  157. INSERT INTO `CRM_UI_MSGS` (`ID`
  158. , `app_className`, `msg`, `msgType`
  159. , `uiTargetType`, `uiTargetName`
  160. , `userTargetType`
  161. , `A_RECORD_CREATE_DATE`, `A_RECORD_CREATE_AUTHOR`)
  162. VALUES (NULL
  163. , 'FixZasobPath', 'Update all paths', 'danger'
  164. , 'default_db_table', 'CRM_LISTA_ZASOBOW'
  165. , 'everyone'
  166. , NOW(), NEW.A_RECORD_UPDATE_AUTHOR
  167. );
  168. END IF;
  169. SQL_QUERY;
  170. $formFixProjectPath = <<<SQL_QUERY
  171. CALL CRM_UI_MSGS__addTableEveryoneUniqueMsg(NEW.A_RECORD_UPDATE_AUTHOR, 'FixProjectPath', 'danger', 'Update all paths', 'IN7_MK_BAZA_DYSTRYBUCJI');
  172. IF (select count(1) from `CRM_UI_MSGS` where `app_className`='FixProjectPath'
  173. and `msg`='Update all paths'
  174. and `uiTargetType`='default_db_table'
  175. and `uiTargetName`='IN7_MK_BAZA_DYSTRYBUCJI'
  176. and `A_STATUS`='WAITING'
  177. ) = 0 THEN
  178. INSERT INTO `CRM_UI_MSGS` (`ID`
  179. , `app_className`, `msg`, `msgType`
  180. , `uiTargetType`, `uiTargetName`
  181. , `userTargetType`
  182. , `A_RECORD_CREATE_DATE`, `A_RECORD_CREATE_AUTHOR`)
  183. VALUES (NULL
  184. , 'FixProjectPath', 'Update all paths', 'danger'
  185. , 'default_db_table', 'IN7_MK_BAZA_DYSTRYBUCJI'
  186. , 'everyone'
  187. , NOW(), NEW.A_RECORD_UPDATE_AUTHOR
  188. );
  189. END IF;
  190. SQL_QUERY;
  191. $db = DB::getDB();
  192. if ($db->has_errors()) {
  193. throw new Exception("DB Errors: " . implode("\n<br>", $db->get_errors()));
  194. }
  195. foreach ($sqlList as $sqlName => $sql) {
  196. $res = $db->query($sql);
  197. if ($db->has_errors()) {
  198. throw new Exception("DB Errors at sql '{$sqlName}': " . implode("\n<br>", $db->get_errors()));
  199. }
  200. }
  201. }
  202. public function reinstall() {
  203. $sqlList = array();
  204. $sqlList['RemoveTable'] = "DROP TABLE IF EXISTS `CRM_UI_MSGS`";
  205. $sqlList['InstallTable'] = "
  206. CREATE TABLE IF NOT EXISTS `CRM_UI_MSGS` (
  207. `ID` int(11) NOT NULL AUTO_INCREMENT
  208. -- app_className - for automatic msgs to search for msg text
  209. , `app_className` varchar(255) DEFAULT NULL
  210. -- msg - msg to show or to parse by app_className
  211. , `msg` varchar(1000) NOT NULL
  212. , `msgType` enum('info','danger','warning','success') NOT NULL DEFAULT 'info'
  213. -- uiTargetType - where to show this msg eg. 'default_db_table', 'after_login', 'everywhere'
  214. , `uiTargetType` varchar(255) NOT NULL DEFAULT ''
  215. -- uiTargetName - eg. database table name (if from default_db)
  216. , `uiTargetName` varchar(255) NOT NULL DEFAULT ''
  217. -- userTargetType - type of users allowed to see this msg eg. 'everyone', 'admin' (ADMIN_LEVEL=0?), 'user', 'group'
  218. , `userTargetType` enum('none','everyone','admin','user','group') NOT NULL DEFAULT 'none'
  219. -- userTargetName - login, group name
  220. , `userTargetName` varchar(255) NOT NULL DEFAULT ''
  221. -- actionExecutedTime - execution time if msg require user to run specific action (send msg.id in request)
  222. , `actionExecutedTime` datetime DEFAULT NULL
  223. -- actionNotes - notes/msgs/dbg for user actions executed from this msg
  224. , `actionNotes` varchar(255) NOT NULL DEFAULT ''
  225. , `A_STATUS` enum('WAITING','NORMAL','OFF_HARD','DELETED') NOT NULL DEFAULT 'WAITING'
  226. , `A_RECORD_CREATE_DATE` datetime DEFAULT NULL
  227. , `A_RECORD_CREATE_AUTHOR` varchar(40) NOT NULL DEFAULT ''
  228. , `A_RECORD_UPDATE_DATE` datetime DEFAULT NULL
  229. , `A_RECORD_UPDATE_AUTHOR` varchar(40) NOT NULL DEFAULT ''
  230. , PRIMARY KEY (`ID`)
  231. , KEY `app_className` (`app_className`)
  232. ) ENGINE=MyISAM DEFAULT CHARSET=latin2
  233. ";
  234. $db = DB::getDB();
  235. if ($db->has_errors()) {
  236. throw new Exception("DB Errors: " . implode("\n<br>", $db->get_errors()));
  237. }
  238. foreach ($sqlList as $sqlName => $sql) {
  239. $res = $db->query($sql);
  240. if ($db->has_errors()) {
  241. throw new Exception("DB Errors at sql '{$sqlName}': " . implode("\n<br>", $db->get_errors()));
  242. }
  243. }
  244. $this->reinstallFunctions();
  245. }
  246. public function getActiveMessagesForTable($tblName) {
  247. if (empty($tblName)) return;
  248. $db = DB::getDB();
  249. $tblName = $db->_($tblName);
  250. $usrLogin = User::getLogin();
  251. $msgs = null;
  252. $sql = "select m.*
  253. from `CRM_UI_MSGS` m
  254. where m.`uiTargetType`='default_db_table'
  255. and m.`A_STATUS`='WAITING'
  256. and m.`uiTargetName`='{$tblName}'
  257. and (m.`userTargetType` in('everyone')
  258. or (m.`userTargetType`='user' and m.`userTargetName`='{$usrLogin}')
  259. -- TODO: use 'admin', 'group'
  260. )
  261. ";
  262. $db = DB::getDB();
  263. $res = $db->query($sql);
  264. while ($r = $db->fetch($res)) {
  265. if ($msg = $this->parseMessage($r)) {
  266. $msg['link'] = 'index.php?_route=Msgs&_task=run&_msgId=' . $r->ID;
  267. $msg['linkType'] = 'ajax';
  268. $msgs[$r->ID] = $msg;
  269. }
  270. }
  271. return $msgs;
  272. }
  273. public function getActiveMessagesForTableRecord($tblName, $id) {
  274. if (empty($tblName)) return;
  275. $db = DB::getDB();
  276. $tblName = $db->_($tblName);
  277. $usrLogin = User::getLogin();
  278. $msgs = null;
  279. $sql = "select m.*
  280. from `CRM_UI_MSGS` m
  281. where m.`uiTargetType`='default_db_table_record'
  282. and m.`uiTargetName`='{$tblName}.{$id}'
  283. and (m.`userTargetType` in('everyone')
  284. or (m.`userTargetType`='user' and m.`userTargetName`='{$usrLogin}')
  285. -- TODO: use group id
  286. )
  287. and m.`A_STATUS`='WAITING'
  288. order by m.`ID` DESC
  289. ";
  290. $db = DB::getDB();
  291. $res = $db->query($sql);
  292. while ($r = $db->fetch($res)) {
  293. if ($msg = $this->parseMessage($r)) {
  294. $msg['link'] = 'index.php?_route=Msgs&_task=run&_msgId=' . $r->ID;
  295. $msg['linkType'] = 'ajax';
  296. $msgs[$r->ID] = $msg;
  297. }
  298. }
  299. return $msgs;
  300. }
  301. public function getMessagesForTableRecord($tblName, $id) {
  302. $msgs = array();
  303. if (empty($tblName)) return $msgs;
  304. $db = DB::getDB();
  305. $tblName = $db->_($tblName);
  306. $usrLogin = User::getLogin();
  307. $sql = "select m.*
  308. from `CRM_UI_MSGS` m
  309. where m.`uiTargetType`='default_db_table_record'
  310. and m.`uiTargetName`='{$tblName}.{$id}'
  311. and (m.`userTargetType` in('everyone')
  312. or (m.`userTargetType`='user' and m.`userTargetName`='{$usrLogin}')
  313. -- TODO: use group id
  314. )
  315. and m.`A_STATUS` not in('DELETED')
  316. order by m.`ID` DESC
  317. ";
  318. $db = DB::getDB();
  319. $res = $db->query($sql);
  320. while ($r = $db->fetch($res)) {
  321. if ($msg = $this->parseMessage($r)) {
  322. $msg['link'] = 'index.php?_route=Msgs&_task=run&_msgId=' . $r->ID;
  323. $msg['linkType'] = 'ajax';
  324. $msgs[$r->ID] = $msg;
  325. }
  326. }
  327. return $msgs;
  328. }
  329. public function getSentMessagesForTableRecord($tblName, $id) {
  330. $msgs = array();
  331. if (empty($tblName)) return $msgs;
  332. $db = DB::getDB();
  333. $tblName = $db->_($tblName);
  334. $usrLogin = User::getLogin();
  335. $sql = "select m.*
  336. from `CRM_UI_MSGS` m
  337. where m.`uiTargetType`='default_db_table_record'
  338. and m.`uiTargetName`='{$tblName}.{$id}'
  339. and m.`A_RECORD_CREATE_AUTHOR`='{$usrLogin}'
  340. and m.`A_STATUS` not in('DELETED')
  341. order by m.`ID` DESC
  342. ";
  343. $db = DB::getDB();
  344. $res = $db->query($sql);
  345. while ($r = $db->fetch($res)) {
  346. if ($msg = $this->parseMessage($r)) {
  347. $msg['link'] = 'index.php?_route=Msgs&_task=run&_msgId=' . $r->ID;
  348. $msg['linkType'] = 'ajax';
  349. $msgs[$r->ID] = $msg;
  350. }
  351. }
  352. return $msgs;
  353. }
  354. public function parseMessage($r) {
  355. $msg = null;// ['type'=>'info', 'message'=>'...']
  356. // $r->app_className - for automatic msgs to search for msg text
  357. // $r->msg - for automatic msgs to search for msg text
  358. // $r->msgType - 'info','danger','warning','success'
  359. if (!empty($r->app_className)) {
  360. $route = Router::getRoute($r->app_className);
  361. $msg = array();
  362. $msg['message'] = $route->parseMessageFromMsgsSystem($r->msg);
  363. $msg['type'] = $r->msgType;
  364. $msg['_raw'] = $r;
  365. } else {
  366. $msg = array();
  367. $msg['message'] = $this->parseMessageFromMsgsSystem($r->msg);
  368. $msg['type'] = $r->msgType;
  369. $msg['_raw'] = $r;
  370. }
  371. return $msg;
  372. }
  373. public function parseMessageFromMsgsSystem($msg) {
  374. return $msg;
  375. }
  376. public function runByMessageId($id) {
  377. $msgRow = $this->getActiveMessage($id);
  378. $execNotes = '';
  379. if (!empty($msgRow->app_className)) {
  380. $route = Router::getRoute($msgRow->app_className);
  381. $route->runByMessageFromMsgsSystem($msgRow->msg, $execNotes);
  382. }
  383. $this->forceFinishMessage($id, $execNotes);
  384. }
  385. public function getMessage($id) {
  386. if (empty($id)) return;
  387. $id = intval($id);
  388. if ($id <= 0) return;
  389. $msg = null;
  390. $sql = "select * from `CRM_UI_MSGS` where `ID`='{$id}' ";
  391. $db = DB::getDB();
  392. $res = $db->query($sql);
  393. if ($r = $db->fetch($res)) {
  394. $msg = $r;
  395. }
  396. return $msg;
  397. }
  398. public function getActiveMessage($id) {
  399. if (empty($id)) return;
  400. $id = intval($id);
  401. if ($id <= 0) return;
  402. $msg = null;
  403. $sql = "select m.*
  404. from `CRM_UI_MSGS` m
  405. where m.`ID`='{$id}'
  406. and m.`A_STATUS`='WAITING'
  407. ";
  408. $db = DB::getDB();
  409. $res = $db->query($sql);
  410. if ($r = $db->fetch($res)) {
  411. $msg = $r;
  412. }
  413. if (!$msg) {
  414. throw new HttpException("Message not found", 404);
  415. }
  416. return $msg;
  417. }
  418. public function forceFinishMessage($id, $execNotes) {
  419. if (empty($id)) return;
  420. $id = intval($id);
  421. if ($id <= 0) return;
  422. $usrLogin = User::getLogin();
  423. $db = DB::getDB();
  424. $execNotes = $db->_($execNotes);
  425. $sql = "update `CRM_UI_MSGS`
  426. set `A_STATUS`='OFF_HARD'
  427. , `actionExecutedTime`=NOW()
  428. , `actionNotes`='{$execNotes}'
  429. , `A_RECORD_UPDATE_DATE`=NOW()
  430. , `A_RECORD_UPDATE_AUTHOR`='{$usrLogin}'
  431. where `ID`='{$id}'
  432. ";
  433. $db->query($sql);
  434. return;
  435. }
  436. public function removeMessage($id) {
  437. if (empty($id)) return;
  438. $id = intval($id);
  439. if ($id <= 0) return;
  440. $sql = "update `CRM_UI_MSGS` set `A_STATUS`='DELETED' where `ID`='{$id}' ";
  441. $db = DB::getDB();
  442. $db->query($sql);
  443. }
  444. }