Msgs.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  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. $exampleFromCrmProcesInitIdx = <<<SQL_QUERY
  100. CALL CRM_UI_MSGS__markTableEveryoneAsExecuted('update_proces_init_idx_rec','FixCrmProcesInitIdx','Update perms','CRM_PROCES');
  101. update `CRM_UI_MSGS`
  102. set `A_STATUS`='OFF_HARD'
  103. , `actionExecutedTime`=NOW()
  104. , `A_RECORD_UPDATE_DATE`=NOW()
  105. , `A_RECORD_UPDATE_AUTHOR`='update_proces_init_idx_rec'
  106. where `A_STATUS`='WAITING'
  107. and `app_className`='FixCrmProcesInitIdx'
  108. and `msg`='Update perms'
  109. and `uiTargetType`='default_db_table'
  110. and `uiTargetName`='CRM_PROCES'
  111. ;
  112. SQL_QUERY;
  113. $exampleFromFixProjectPath = <<<SQL_QUERY
  114. CALL CRM_UI_MSGS__markTableEveryoneAsExecuted('update_zasob_path_idx_rec','FixProjectPath','Update all paths','IN7_MK_BAZA_DYSTRYBUCJI');
  115. update `CRM_UI_MSGS`
  116. set `A_STATUS`='OFF_HARD'
  117. , `actionExecutedTime`=NOW()
  118. , `A_RECORD_UPDATE_DATE`=NOW()
  119. , `A_RECORD_UPDATE_AUTHOR`='update_zasob_path_idx_rec'
  120. where `A_STATUS`='WAITING'
  121. and `app_className`='FixProjectPath'
  122. and `msg`='Update all paths'
  123. and `uiTargetType`='default_db_table'
  124. and `uiTargetName`='IN7_MK_BAZA_DYSTRYBUCJI';
  125. SQL_QUERY;
  126. $exampleFromFixZasobPath = <<<SQL_QUERY
  127. CALL CRM_UI_MSGS__markTableEveryoneAsExecuted('update_zasob_path_idx_rec','FixZasobPath','Update all paths','CRM_LISTA_ZASOBOW');
  128. update `CRM_UI_MSGS`
  129. set `A_STATUS`='OFF_HARD'
  130. , `actionExecutedTime`=NOW()
  131. , `A_RECORD_UPDATE_DATE`=NOW()
  132. , `A_RECORD_UPDATE_AUTHOR`='update_zasob_path_idx_rec'
  133. where `A_STATUS`='WAITING'
  134. and `app_className`='FixZasobPath'
  135. and `msg`='Update all paths'
  136. and `uiTargetType`='default_db_table'
  137. and `uiTargetName`='CRM_LISTA_ZASOBOW';
  138. SQL_QUERY;
  139. $db = DB::getDB();
  140. if ($db->has_errors()) {
  141. throw new Exception("DB Errors: " . implode("\n<br>", $db->get_errors()));
  142. }
  143. foreach ($sqlList as $sqlName => $sql) {
  144. $res = $db->query($sql);
  145. if ($db->has_errors()) {
  146. throw new Exception("DB Errors at sql '{$sqlName}': " . implode("\n<br>", $db->get_errors()));
  147. }
  148. }
  149. }
  150. public function reinstall() {
  151. $sqlList = array();
  152. $sqlList['RemoveTable'] = "DROP TABLE IF EXISTS `CRM_UI_MSGS`";
  153. $sqlList['InstallTable'] = "
  154. CREATE TABLE IF NOT EXISTS `CRM_UI_MSGS` (
  155. `ID` int(11) NOT NULL AUTO_INCREMENT
  156. -- app_className - for automatic msgs to search for msg text
  157. , `app_className` varchar(255) DEFAULT NULL
  158. -- msg - msg to show or to parse by app_className
  159. , `msg` varchar(255) NOT NULL
  160. , `msgType` enum('info','danger','warning','success') NOT NULL DEFAULT 'info'
  161. -- uiTargetType - where to show this msg eg. 'default_db_table', 'after_login', 'everywhere'
  162. , `uiTargetType` varchar(255) NOT NULL DEFAULT ''
  163. -- uiTargetName - eg. database table name (if from default_db)
  164. , `uiTargetName` varchar(255) NOT NULL DEFAULT ''
  165. -- userTargetType - type of users allowed to see this msg eg. 'everyone', 'admin' (ADMIN_LEVEL=0?), 'user', 'group'
  166. , `userTargetType` enum('none','everyone','admin','user','group') NOT NULL DEFAULT 'none'
  167. -- userTargetName - login, group name
  168. , `userTargetName` varchar(255) NOT NULL DEFAULT ''
  169. -- actionExecutedTime - execution time if msg require user to run specific action (send msg.id in request)
  170. , `actionExecutedTime` datetime DEFAULT NULL
  171. -- actionNotes - notes/msgs/dbg for user actions executed from this msg
  172. , `actionNotes` varchar(255) NOT NULL DEFAULT ''
  173. , `A_STATUS` enum('WAITING','NORMAL','OFF_HARD','DELETED') NOT NULL DEFAULT 'WAITING'
  174. , `A_RECORD_CREATE_DATE` datetime DEFAULT NULL
  175. , `A_RECORD_CREATE_AUTHOR` varchar(40) NOT NULL DEFAULT ''
  176. , `A_RECORD_UPDATE_DATE` datetime DEFAULT NULL
  177. , `A_RECORD_UPDATE_AUTHOR` varchar(40) NOT NULL DEFAULT ''
  178. , PRIMARY KEY (`ID`)
  179. , KEY `app_className` (`app_className`)
  180. ) ENGINE=MyISAM DEFAULT CHARSET=latin2
  181. ";
  182. $db = DB::getDB();
  183. if ($db->has_errors()) {
  184. throw new Exception("DB Errors: " . implode("\n<br>", $db->get_errors()));
  185. }
  186. foreach ($sqlList as $sqlName => $sql) {
  187. $res = $db->query($sql);
  188. if ($db->has_errors()) {
  189. throw new Exception("DB Errors at sql '{$sqlName}': " . implode("\n<br>", $db->get_errors()));
  190. }
  191. }
  192. $this->reinstallFunctions();
  193. }
  194. public function getActiveMessagesForTable($tblName) {
  195. if (empty($tblName)) return;
  196. $db = DB::getDB();
  197. $tblName = $db->_($tblName);
  198. $usrLogin = User::getLogin();
  199. $msgs = null;
  200. $sql = "select m.*
  201. from `CRM_UI_MSGS` m
  202. where m.`uiTargetType`='default_db_table'
  203. and m.`A_STATUS`='WAITING'
  204. and m.`uiTargetName`='{$tblName}'
  205. and (m.`userTargetType` in('everyone')
  206. or (m.`userTargetType`='user' and m.`userTargetName`='{$usrLogin}')
  207. -- TODO: use 'admin', 'group'
  208. )
  209. ";
  210. $db = DB::getDB();
  211. $res = $db->query($sql);
  212. while ($r = $db->fetch($res)) {
  213. if ($msg = $this->parseMessage($r)) {
  214. $msg['link'] = 'index.php?_route=Msgs&_task=run&_msgId=' . $r->ID;
  215. $msg['linkType'] = 'ajax';
  216. $msgs[$r->ID] = $msg;
  217. }
  218. }
  219. return $msgs;
  220. }
  221. public function parseMessage($r) {
  222. $msg = null;// ['type'=>'info', 'message'=>'...']
  223. // $r->app_className - for automatic msgs to search for msg text
  224. // $r->msg - for automatic msgs to search for msg text
  225. // $r->msgType - 'info','danger','warning','success'
  226. if (!empty($r->app_className)) {
  227. $route = Router::getRoute($r->app_className);
  228. $msg = array();
  229. $msg['message'] = $route->parseMessageFromMsgsSystem($r->msg);
  230. $msg['type'] = $r->msgType;
  231. } else {
  232. $msg = array();
  233. $msg['message'] = $this->parseMessageFromMsgsSystem($r->msg);
  234. $msg['type'] = $r->msgType;
  235. }
  236. return $msg;
  237. }
  238. public function parseMessageFromMsgsSystem($msg) {
  239. return $msg;
  240. }
  241. public function runByMessageId($id) {
  242. $msgRow = $this->getActiveMessage($id);
  243. $execNotes = '';
  244. if (!empty($msgRow->app_className)) {
  245. $route = Router::getRoute($msgRow->app_className);
  246. $route->runByMessageFromMsgsSystem($msgRow->msg, $execNotes);
  247. }
  248. $this->forceFinishMessage($id, $execNotes);
  249. }
  250. public function getMessage($id) {
  251. if (empty($id)) return;
  252. $id = intval($id);
  253. if ($id <= 0) return;
  254. $msg = null;
  255. $sql = "select * from `CRM_UI_MSGS` where `ID`='{$id}' ";
  256. $db = DB::getDB();
  257. $res = $db->query($sql);
  258. if ($r = $db->fetch($res)) {
  259. $msg = $r;
  260. }
  261. return $msg;
  262. }
  263. public function getActiveMessage($id) {
  264. if (empty($id)) return;
  265. $id = intval($id);
  266. if ($id <= 0) return;
  267. $msg = null;
  268. $sql = "select m.*
  269. from `CRM_UI_MSGS` m
  270. where m.`ID`='{$id}'
  271. and m.`A_STATUS`='WAITING'
  272. ";
  273. $db = DB::getDB();
  274. $res = $db->query($sql);
  275. if ($r = $db->fetch($res)) {
  276. $msg = $r;
  277. }
  278. if (!$msg) {
  279. throw new HttpException("Message not found", 404);
  280. }
  281. return $msg;
  282. }
  283. public function forceFinishMessage($id, $execNotes) {
  284. if (empty($id)) return;
  285. $id = intval($id);
  286. if ($id <= 0) return;
  287. $usrLogin = User::getLogin();
  288. $db = DB::getDB();
  289. $execNotes = $db->_($execNotes);
  290. $sql = "update `CRM_UI_MSGS`
  291. set `A_STATUS`='OFF_HARD'
  292. , `actionExecutedTime`=NOW()
  293. , `actionNotes`='{$execNotes}'
  294. , `A_RECORD_UPDATE_DATE`=NOW()
  295. , `A_RECORD_UPDATE_AUTHOR`='{$usrLogin}'
  296. where `ID`='{$id}'
  297. ";
  298. $db->query($sql);
  299. return;
  300. }
  301. public function removeMessage($id) {
  302. if (empty($id)) return;
  303. $id = intval($id);
  304. if ($id <= 0) return;
  305. $sql = "update `CRM_UI_MSGS` set `A_STATUS`='DELETED' where `ID`='{$id}' ";
  306. $db = DB::getDB();
  307. $db->query($sql);
  308. }
  309. }