Msgs.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  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(255) 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 parseMessage($r) {
  274. $msg = null;// ['type'=>'info', 'message'=>'...']
  275. // $r->app_className - for automatic msgs to search for msg text
  276. // $r->msg - for automatic msgs to search for msg text
  277. // $r->msgType - 'info','danger','warning','success'
  278. if (!empty($r->app_className)) {
  279. $route = Router::getRoute($r->app_className);
  280. $msg = array();
  281. $msg['message'] = $route->parseMessageFromMsgsSystem($r->msg);
  282. $msg['type'] = $r->msgType;
  283. } else {
  284. $msg = array();
  285. $msg['message'] = $this->parseMessageFromMsgsSystem($r->msg);
  286. $msg['type'] = $r->msgType;
  287. }
  288. return $msg;
  289. }
  290. public function parseMessageFromMsgsSystem($msg) {
  291. return $msg;
  292. }
  293. public function runByMessageId($id) {
  294. $msgRow = $this->getActiveMessage($id);
  295. $execNotes = '';
  296. if (!empty($msgRow->app_className)) {
  297. $route = Router::getRoute($msgRow->app_className);
  298. $route->runByMessageFromMsgsSystem($msgRow->msg, $execNotes);
  299. }
  300. $this->forceFinishMessage($id, $execNotes);
  301. }
  302. public function getMessage($id) {
  303. if (empty($id)) return;
  304. $id = intval($id);
  305. if ($id <= 0) return;
  306. $msg = null;
  307. $sql = "select * from `CRM_UI_MSGS` where `ID`='{$id}' ";
  308. $db = DB::getDB();
  309. $res = $db->query($sql);
  310. if ($r = $db->fetch($res)) {
  311. $msg = $r;
  312. }
  313. return $msg;
  314. }
  315. public function getActiveMessage($id) {
  316. if (empty($id)) return;
  317. $id = intval($id);
  318. if ($id <= 0) return;
  319. $msg = null;
  320. $sql = "select m.*
  321. from `CRM_UI_MSGS` m
  322. where m.`ID`='{$id}'
  323. and m.`A_STATUS`='WAITING'
  324. ";
  325. $db = DB::getDB();
  326. $res = $db->query($sql);
  327. if ($r = $db->fetch($res)) {
  328. $msg = $r;
  329. }
  330. if (!$msg) {
  331. throw new HttpException("Message not found", 404);
  332. }
  333. return $msg;
  334. }
  335. public function forceFinishMessage($id, $execNotes) {
  336. if (empty($id)) return;
  337. $id = intval($id);
  338. if ($id <= 0) return;
  339. $usrLogin = User::getLogin();
  340. $db = DB::getDB();
  341. $execNotes = $db->_($execNotes);
  342. $sql = "update `CRM_UI_MSGS`
  343. set `A_STATUS`='OFF_HARD'
  344. , `actionExecutedTime`=NOW()
  345. , `actionNotes`='{$execNotes}'
  346. , `A_RECORD_UPDATE_DATE`=NOW()
  347. , `A_RECORD_UPDATE_AUTHOR`='{$usrLogin}'
  348. where `ID`='{$id}'
  349. ";
  350. $db->query($sql);
  351. return;
  352. }
  353. public function removeMessage($id) {
  354. if (empty($id)) return;
  355. $id = intval($id);
  356. if ($id <= 0) return;
  357. $sql = "update `CRM_UI_MSGS` set `A_STATUS`='DELETED' where `ID`='{$id}' ";
  358. $db = DB::getDB();
  359. $db->query($sql);
  360. }
  361. }