Msgs.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442
  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['RemoveTable_CRM_UI_MSGS__EXEC_LOG'] = "DROP TABLE IF EXISTS `CRM_UI_MSGS__EXEC_LOG`";
  61. $sqlList['CreateTable_CRM_UI_MSGS__EXEC_LOG'] = "
  62. CREATE TABLE IF NOT EXISTS `CRM_UI_MSGS__EXEC_LOG` (
  63. `ID` int(11) NOT NULL AUTO_INCREMENT
  64. , `_exec_time` datetime DEFAULT NULL
  65. , `author` VARCHAR(40) DEFAULT ''
  66. , `app_className` VARCHAR(255) DEFAULT ''
  67. , `msg` VARCHAR(255) DEFAULT ''
  68. , `uiTargetType` VARCHAR(255) DEFAULT ''
  69. , `uiTargetName` VARCHAR(255) DEFAULT ''
  70. , `userTargetType` VARCHAR(255) DEFAULT ''
  71. , `userTargetName` VARCHAR(255) DEFAULT ''
  72. , PRIMARY KEY (`ID`)
  73. ) ENGINE=MyISAM DEFAULT CHARSET=latin2
  74. ";
  75. $sqlList['RemoveProcedureMarkAsExecuted'] = "DROP PROCEDURE IF EXISTS `CRM_UI_MSGS__markAsExecuted`";
  76. $sqlList['InstallProcedureMarkAsExecuted'] = <<<SQL_QUERY
  77. CREATE DEFINER=`root`@`localhost` PROCEDURE `CRM_UI_MSGS__markAsExecuted`(
  78. IN author VARCHAR(40),
  79. IN app_className VARCHAR(255),
  80. IN msg VARCHAR(255),
  81. IN uiTargetType VARCHAR(255),
  82. IN uiTargetName VARCHAR(255),
  83. IN userTargetType VARCHAR(255),
  84. IN userTargetName VARCHAR(255)
  85. )
  86. BEGIN
  87. -- insert into `CRM_UI_MSGS__EXEC_LOG`
  88. -- (`author`, `app_className`, `msg`, `uiTargetType`, `uiTargetName`, `userTargetType`, `userTargetName`, `_exec_time`)
  89. -- values(author, app_className, msg, uiTargetType, uiTargetName, userTargetType, userTargetName, NOW());
  90. update `CRM_UI_MSGS` m
  91. set m.`A_STATUS`='OFF_HARD'
  92. , m.`actionExecutedTime`=NOW()
  93. , m.`A_RECORD_UPDATE_DATE`=NOW()
  94. , m.`A_RECORD_UPDATE_AUTHOR`=author
  95. where m.`A_STATUS`='WAITING' -- TODO: not in('DELETED', 'OFF_HARD')
  96. and m.`app_className`=app_className
  97. and m.`msg`=msg
  98. and m.`uiTargetType`=uiTargetType
  99. and m.`uiTargetName`=uiTargetName
  100. and m.`userTargetType`=userTargetType
  101. and m.`userTargetName`=userTargetName
  102. ;
  103. END
  104. SQL_QUERY;
  105. $sqlList['RemoveProcedureMarkTableEveryoneAsExecuted'] = "DROP PROCEDURE IF EXISTS `CRM_UI_MSGS__markTableEveryoneAsExecuted`";
  106. $sqlList['InstallProcedureMarkTableEveryoneAsExecuted'] = <<<SQL_QUERY
  107. CREATE DEFINER=`root`@`localhost` PROCEDURE `CRM_UI_MSGS__markTableEveryoneAsExecuted`(
  108. IN author VARCHAR(40),
  109. IN app_className VARCHAR(255),
  110. IN msg VARCHAR(255),
  111. IN uiTargetName VARCHAR(255)
  112. )
  113. BEGIN
  114. CALL CRM_UI_MSGS__markAsExecuted(author, app_className, msg, 'default_db_table', uiTargetName, 'everyone', '');
  115. END
  116. SQL_QUERY;
  117. $sqlList['RemoveProcedureAddUniqueMsg'] = "DROP PROCEDURE IF EXISTS `CRM_UI_MSGS__addUniqueMsg`";
  118. $sqlList['InstallProcedureAddUniqueMsg'] = <<<SQL_QUERY
  119. CREATE DEFINER=`root`@`localhost` PROCEDURE `CRM_UI_MSGS__addUniqueMsg`(
  120. IN author VARCHAR(40),
  121. IN app_className VARCHAR(255),
  122. IN msgType VARCHAR(16),
  123. IN msg VARCHAR(255),
  124. IN uiTargetType VARCHAR(255),
  125. IN uiTargetName VARCHAR(255),
  126. IN userTargetType VARCHAR(255),
  127. IN userTargetName VARCHAR(255)
  128. )
  129. BEGIN
  130. IF (select count(1)
  131. from `CRM_UI_MSGS`
  132. where `app_className`=app_className
  133. and `msg`=msg
  134. and `uiTargetType`=uiTargetType
  135. and `uiTargetName`=uiTargetName
  136. and `userTargetType`=userTargetType
  137. and `userTargetName`=userTargetName
  138. and `A_STATUS`='WAITING'
  139. ) = 0 THEN
  140. INSERT INTO `CRM_UI_MSGS` (`ID`
  141. , `app_className`, `msg`, `msgType`
  142. , `uiTargetType`, `uiTargetName`
  143. , `userTargetType`, `userTargetName`
  144. , `A_RECORD_CREATE_DATE`, `A_RECORD_CREATE_AUTHOR`)
  145. VALUES (NULL
  146. , app_className, msg, msgType
  147. , uiTargetType, uiTargetName
  148. , userTargetType, userTargetName
  149. , NOW(), author
  150. );
  151. END IF;
  152. END
  153. SQL_QUERY;
  154. $sqlList['RemoveProcedureAddTableEveryoneUniqueMsg'] = "DROP PROCEDURE IF EXISTS `CRM_UI_MSGS__addTableEveryoneUniqueMsg`";
  155. $sqlList['InstallProcedureAddTableEveryoneUniqueMsg'] = <<<SQL_QUERY
  156. CREATE DEFINER=`root`@`localhost` PROCEDURE `CRM_UI_MSGS__addTableEveryoneUniqueMsg`(
  157. IN author VARCHAR(40),
  158. IN app_className VARCHAR(255),
  159. IN msgType VARCHAR(16),
  160. IN msg VARCHAR(255),
  161. IN uiTargetName VARCHAR(255)
  162. )
  163. BEGIN
  164. CALL CRM_UI_MSGS__addUniqueMsg(author, app_className, msgType, msg, 'default_db_table', uiTargetName, 'everyone', '');
  165. END
  166. SQL_QUERY;
  167. $formFixZasobPath = <<<SQL_QUERY
  168. CALL CRM_UI_MSGS__addTableEveryoneUniqueMsg(NEW.A_RECORD_UPDATE_AUTHOR, 'FixZasobPath', 'danger', 'Update all paths', 'CRM_LISTA_ZASOBOW');
  169. IF (select count(1) from `CRM_UI_MSGS` where `app_className`='FixZasobPath'
  170. and `msg`='Update all paths'
  171. and `uiTargetType`='default_db_table'
  172. and `uiTargetName`='CRM_LISTA_ZASOBOW'
  173. and `A_STATUS`='WAITING'
  174. ) = 0 THEN
  175. INSERT INTO `CRM_UI_MSGS` (`ID`
  176. , `app_className`, `msg`, `msgType`
  177. , `uiTargetType`, `uiTargetName`
  178. , `userTargetType`
  179. , `A_RECORD_CREATE_DATE`, `A_RECORD_CREATE_AUTHOR`)
  180. VALUES (NULL
  181. , 'FixZasobPath', 'Update all paths', 'danger'
  182. , 'default_db_table', 'CRM_LISTA_ZASOBOW'
  183. , 'everyone'
  184. , NOW(), NEW.A_RECORD_UPDATE_AUTHOR
  185. );
  186. END IF;
  187. SQL_QUERY;
  188. $formFixProjectPath = <<<SQL_QUERY
  189. CALL CRM_UI_MSGS__addTableEveryoneUniqueMsg(NEW.A_RECORD_UPDATE_AUTHOR, 'FixProjectPath', 'danger', 'Update all paths', 'IN7_MK_BAZA_DYSTRYBUCJI');
  190. IF (select count(1) from `CRM_UI_MSGS` where `app_className`='FixProjectPath'
  191. and `msg`='Update all paths'
  192. and `uiTargetType`='default_db_table'
  193. and `uiTargetName`='IN7_MK_BAZA_DYSTRYBUCJI'
  194. and `A_STATUS`='WAITING'
  195. ) = 0 THEN
  196. INSERT INTO `CRM_UI_MSGS` (`ID`
  197. , `app_className`, `msg`, `msgType`
  198. , `uiTargetType`, `uiTargetName`
  199. , `userTargetType`
  200. , `A_RECORD_CREATE_DATE`, `A_RECORD_CREATE_AUTHOR`)
  201. VALUES (NULL
  202. , 'FixProjectPath', 'Update all paths', 'danger'
  203. , 'default_db_table', 'IN7_MK_BAZA_DYSTRYBUCJI'
  204. , 'everyone'
  205. , NOW(), NEW.A_RECORD_UPDATE_AUTHOR
  206. );
  207. END IF;
  208. SQL_QUERY;
  209. $db = DB::getDB();
  210. if ($db->has_errors()) {
  211. throw new Exception("DB Errors: " . implode("\n<br>", $db->get_errors()));
  212. }
  213. foreach ($sqlList as $sqlName => $sql) {
  214. $res = $db->query($sql);
  215. if ($db->has_errors()) {
  216. throw new Exception("DB Errors at sql '{$sqlName}': " . implode("\n<br>", $db->get_errors()));
  217. }
  218. }
  219. }
  220. public function reinstall() {
  221. $sqlList = array();
  222. $sqlList['RemoveTable'] = "DROP TABLE IF EXISTS `CRM_UI_MSGS`";
  223. $sqlList['InstallTable'] = "
  224. CREATE TABLE IF NOT EXISTS `CRM_UI_MSGS` (
  225. `ID` int(11) NOT NULL AUTO_INCREMENT
  226. -- app_className - for automatic msgs to search for msg text
  227. , `app_className` varchar(255) DEFAULT NULL
  228. -- msg - msg to show or to parse by app_className
  229. , `msg` varchar(1000) NOT NULL
  230. , `msgType` enum('info','danger','warning','success') NOT NULL DEFAULT 'info'
  231. -- uiTargetType - where to show this msg eg. 'default_db_table', 'after_login', 'everywhere'
  232. , `uiTargetType` enum('default_db_table','default_db_table_record','after_login','everywhere') NOT NULL
  233. -- uiTargetName - eg. database table name (if from default_db)
  234. , `uiTargetName` varchar(255) NOT NULL DEFAULT ''
  235. -- userTargetType - type of users allowed to see this msg eg. 'everyone', 'admin' (ADMIN_LEVEL=0?), 'user', 'group'
  236. , `userTargetType` enum('none','everyone','admin','user','group') NOT NULL DEFAULT 'none'
  237. -- userTargetName - login, group name
  238. , `userTargetName` varchar(255) NOT NULL DEFAULT ''
  239. -- actionExecutedTime - execution time if msg require user to run specific action (send msg.id in request)
  240. , `actionExecutedTime` datetime DEFAULT NULL
  241. -- actionNotes - notes/msgs/dbg for user actions executed from this msg
  242. , `actionNotes` varchar(255) NOT NULL DEFAULT ''
  243. , `A_STATUS` enum('WAITING','NORMAL','OFF_HARD','DELETED') NOT NULL DEFAULT 'WAITING'
  244. , `A_RECORD_CREATE_DATE` datetime DEFAULT NULL
  245. , `A_RECORD_CREATE_AUTHOR` varchar(40) NOT NULL DEFAULT ''
  246. , `A_RECORD_UPDATE_DATE` datetime DEFAULT NULL
  247. , `A_RECORD_UPDATE_AUTHOR` varchar(40) NOT NULL DEFAULT ''
  248. , `A_RECORD_DELETE_DATE` datetime DEFAULT NULL
  249. , `A_RECORD_DELETE_AUTHOR` varchar(40) NOT NULL DEFAULT ''
  250. , PRIMARY KEY (`ID`)
  251. , KEY `app_className` (`app_className`)
  252. ) ENGINE=MyISAM DEFAULT CHARSET=latin2
  253. ";
  254. $db = DB::getDB();
  255. if ($db->has_errors()) {
  256. throw new Exception("DB Errors: " . implode("\n<br>", $db->get_errors()));
  257. }
  258. foreach ($sqlList as $sqlName => $sql) {
  259. $res = $db->query($sql);
  260. if ($db->has_errors()) {
  261. throw new Exception("DB Errors at sql '{$sqlName}': " . implode("\n<br>", $db->get_errors()));
  262. }
  263. }
  264. $this->reinstallFunctions();
  265. }
  266. public function getActiveMessagesForTable($tblName) {
  267. if (empty($tblName)) return;
  268. $db = DB::getDB();
  269. $tblName = $db->_($tblName);
  270. $usrLogin = User::getLogin();
  271. $msgs = null;
  272. $sql = "select m.*
  273. from `CRM_UI_MSGS` m
  274. where m.`uiTargetType`='default_db_table'
  275. and m.`A_STATUS`='WAITING'
  276. and m.`uiTargetName`='{$tblName}'
  277. and (m.`userTargetType` in('everyone')
  278. or (m.`userTargetType`='user' and m.`userTargetName`='{$usrLogin}')
  279. -- TODO: use 'admin', 'group'
  280. )
  281. ";
  282. $db = DB::getDB();
  283. $res = $db->query($sql);
  284. while ($r = $db->fetch($res)) {
  285. if ($msg = $this->parseMessage($r)) {
  286. $msg['link'] = 'index.php?_route=Msgs&_task=run&_msgId=' . $r->ID;
  287. $msg['linkType'] = 'ajax';
  288. $msgs[$r->ID] = $msg;
  289. }
  290. }
  291. return $msgs;
  292. }
  293. public function getActiveMessagesForTableRecord($tblName, $id) {
  294. if (empty($tblName)) return;
  295. $db = DB::getDB();
  296. $tblName = $db->_($tblName);
  297. $usrLogin = User::getLogin();
  298. $msgs = null;
  299. $sql = "select m.*
  300. from `CRM_UI_MSGS` m
  301. where m.`uiTargetType`='default_db_table_record'
  302. and m.`uiTargetName`='{$tblName}.{$id}'
  303. and (m.`userTargetType` in('everyone')
  304. or (m.`userTargetType`='user' and m.`userTargetName`='{$usrLogin}')
  305. -- TODO: use group id
  306. )
  307. and m.`A_STATUS`='WAITING'
  308. order by m.`ID` DESC
  309. ";
  310. $db = DB::getDB();
  311. $res = $db->query($sql);
  312. while ($r = $db->fetch($res)) {
  313. if ($msg = $this->parseMessage($r)) {
  314. $msg['link'] = 'index.php?_route=Msgs&_task=run&_msgId=' . $r->ID;
  315. $msg['linkType'] = 'ajax';
  316. $msgs[$r->ID] = $msg;
  317. }
  318. }
  319. return $msgs;
  320. }
  321. public function parseMessage($r) {
  322. $msg = null;// ['type'=>'info', 'message'=>'...']
  323. // $r->app_className - for automatic msgs to search for msg text
  324. // $r->msg - for automatic msgs to search for msg text
  325. // $r->msgType - 'info','danger','warning','success'
  326. if (!empty($r->app_className)) {
  327. $route = Router::getRoute($r->app_className);
  328. $msg = array();
  329. $msg['message'] = $route->parseMessageFromMsgsSystem($r->msg);
  330. $msg['type'] = $r->msgType;
  331. $msg['_raw'] = $r;
  332. } else {
  333. $msg = array();
  334. $msg['message'] = $this->parseMessageFromMsgsSystem($r->msg);
  335. $msg['type'] = $r->msgType;
  336. $msg['_raw'] = $r;
  337. }
  338. return $msg;
  339. }
  340. public function parseMessageFromMsgsSystem($msg) {
  341. return $msg;
  342. }
  343. public function runByMessageId($id) {
  344. $msgRow = $this->getActiveMessage($id);
  345. $execNotes = '';
  346. if (!empty($msgRow->app_className)) {
  347. $route = Router::getRoute($msgRow->app_className);
  348. $route->runByMessageFromMsgsSystem($msgRow->msg, $execNotes);
  349. }
  350. $this->forceFinishMessage($id, $execNotes);
  351. }
  352. public function getMessage($id) {
  353. if (empty($id)) return;
  354. $id = intval($id);
  355. if ($id <= 0) return;
  356. $msg = null;
  357. $sql = "select * from `CRM_UI_MSGS` where `ID`='{$id}' ";
  358. $db = DB::getDB();
  359. $res = $db->query($sql);
  360. if ($r = $db->fetch($res)) {
  361. $msg = $r;
  362. }
  363. return $msg;
  364. }
  365. public function getActiveMessage($id) {
  366. if (empty($id)) return;
  367. $id = intval($id);
  368. if ($id <= 0) return;
  369. $msg = null;
  370. $sql = "select m.*
  371. from `CRM_UI_MSGS` m
  372. where m.`ID`='{$id}'
  373. and m.`A_STATUS`='WAITING'
  374. ";
  375. $db = DB::getDB();
  376. $res = $db->query($sql);
  377. if ($r = $db->fetch($res)) {
  378. $msg = $r;
  379. }
  380. if (!$msg) {
  381. throw new HttpException("Message not found", 404);
  382. }
  383. return $msg;
  384. }
  385. public function forceFinishMessage($id, $execNotes) {
  386. if (empty($id)) return;
  387. $id = intval($id);
  388. if ($id <= 0) return;
  389. $usrLogin = User::getLogin();
  390. $db = DB::getDB();
  391. $execNotes = $db->_($execNotes);
  392. $sql = "update `CRM_UI_MSGS`
  393. set `A_STATUS`='OFF_HARD'
  394. , `actionExecutedTime`=NOW()
  395. , `actionNotes`='{$execNotes}'
  396. , `A_RECORD_UPDATE_DATE`=NOW()
  397. , `A_RECORD_UPDATE_AUTHOR`='{$usrLogin}'
  398. where `ID`='{$id}'
  399. ";
  400. $db->query($sql);
  401. return;
  402. }
  403. public function removeMessage($id) {
  404. if (empty($id)) return;
  405. $id = intval($id);
  406. if ($id <= 0) return;
  407. $sql = "update `CRM_UI_MSGS` set `A_STATUS`='DELETED' where `ID`='{$id}' ";
  408. $db = DB::getDB();
  409. $db->query($sql);
  410. }
  411. }