Bootswatch, Summernote, and Captcheck mods for Mods for HESK (mods-for-hesk.com). In use at support.netsyms.com.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

admin_functions.inc.php 24KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752
  1. <?php
  2. /**
  3. *
  4. * This file is part of HESK - PHP Help Desk Software.
  5. *
  6. * (c) Copyright Klemen Stirn. All rights reserved.
  7. * https://www.hesk.com
  8. *
  9. * For the full copyright and license agreement information visit
  10. * https://www.hesk.com/eula.php
  11. *
  12. */
  13. /* Check if this is a valid include */
  14. if (!defined('IN_SCRIPT')) {
  15. die('Invalid attempt');
  16. }
  17. // Possible fields to be displayed in ticket list
  18. $hesk_settings['possible_ticket_list'] = array(
  19. 'id' => $hesklang['id'],
  20. 'trackid' => $hesklang['trackID'],
  21. 'dt' => $hesklang['submitted'],
  22. 'lastchange' => $hesklang['last_update'],
  23. 'category' => $hesklang['category'],
  24. 'name' => $hesklang['name'],
  25. 'email' => $hesklang['email'],
  26. 'subject' => $hesklang['subject'],
  27. 'status' => $hesklang['status'],
  28. 'owner' => $hesklang['owner'],
  29. 'replies' => $hesklang['replies'],
  30. 'staffreplies' => $hesklang['replies'] . ' (' . $hesklang['staff'] . ')',
  31. 'lastreplier' => $hesklang['last_replier'],
  32. 'time_worked' => $hesklang['ts'],
  33. );
  34. define('HESK_NO_ROBOTS', true);
  35. /*** FUNCTIONS ***/
  36. function hesk_show_column($column)
  37. {
  38. global $hesk_settings;
  39. return in_array($column, $hesk_settings['ticket_list']) ? true : false;
  40. } // END hesk_show_column()
  41. function hesk_getHHMMSS($in)
  42. {
  43. $in = hesk_getTime($in);
  44. return explode(':', $in);
  45. } // END hesk_getHHMMSS();
  46. function hesk_getTime($in)
  47. {
  48. $in = trim($in);
  49. /* If everything is OK this simple check should return true */
  50. if (preg_match('/^([0-9]{2,3}):([0-5][0-9]):([0-5][0-9])$/', $in)) {
  51. return $in;
  52. }
  53. /* No joy, let's try to figure out the correct values to use... */
  54. $h = 0;
  55. $m = 0;
  56. $s = 0;
  57. /* How many parts do we have? */
  58. $parts = substr_count($in, ':');
  59. switch ($parts) {
  60. /* Only two parts, let's assume minutes and seconds */
  61. case 1:
  62. list($m, $s) = explode(':', $in);
  63. break;
  64. /* Three parts, so explode to hours, minutes and seconds */
  65. case 2:
  66. list($h, $m, $s) = explode(':', $in);
  67. break;
  68. /* Something other was entered, let's assume just minutes */
  69. default:
  70. $m = $in;
  71. }
  72. /* Make sure all inputs are integers */
  73. $h = intval($h);
  74. $m = intval($m);
  75. $s = intval($s);
  76. /* Convert seconds to minutes if 60 or more seconds */
  77. if ($s > 59) {
  78. $m = floor($s / 60) + $m;
  79. $s = intval($s % 60);
  80. }
  81. /* Convert minutes to hours if 60 or more minutes */
  82. if ($m > 59) {
  83. $h = floor($m / 60) + $h;
  84. $m = intval($m % 60);
  85. }
  86. /* MySQL accepts max time value of 838:59:59 */
  87. if ($h > 838) {
  88. return '838:59:59';
  89. }
  90. /* That's it, let's send out formatted time string */
  91. return str_pad($h, 2, "0", STR_PAD_LEFT) . ':' . str_pad($m, 2, "0", STR_PAD_LEFT) . ':' . str_pad($s, 2, "0", STR_PAD_LEFT);
  92. } // END hesk_getTime();
  93. function hesk_mergeTickets($merge_these, $merge_into)
  94. {
  95. global $hesk_settings, $hesklang, $hesk_db_link;
  96. /* Target ticket must not be in the "merge these" list */
  97. if (in_array($merge_into, $merge_these)) {
  98. $merge_these = array_diff($merge_these, array($merge_into));
  99. }
  100. /* At least 1 ticket needs to be merged with target ticket */
  101. if (count($merge_these) < 1) {
  102. $_SESSION['error'] = $hesklang['merr1'];
  103. return false;
  104. }
  105. /* Make sure target ticket exists */
  106. $res = hesk_dbQuery("SELECT `id`,`trackid`,`category` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` WHERE `id`='" . intval($merge_into) . "' LIMIT 1");
  107. if (hesk_dbNumRows($res) != 1) {
  108. $_SESSION['error'] = $hesklang['merr2'];
  109. return false;
  110. }
  111. $ticket = hesk_dbFetchAssoc($res);
  112. /* Make sure user has access to ticket category */
  113. if (!hesk_okCategory($ticket['category'], 0)) {
  114. $_SESSION['error'] = $hesklang['merr3'];
  115. return false;
  116. }
  117. /* Set some variables for later */
  118. $merge['attachments'] = '';
  119. $merge['replies'] = array();
  120. $merge['notes'] = array();
  121. $sec_worked = 0;
  122. $history = '';
  123. $merged = '';
  124. /* Get messages, replies, notes and attachments of tickets that will be merged */
  125. foreach ($merge_these as $this_id) {
  126. /* Validate ID */
  127. if (is_array($this_id)) {
  128. continue;
  129. }
  130. $this_id = intval($this_id) or hesk_error($hesklang['id_not_valid']);
  131. /* Get required ticket information */
  132. $res = hesk_dbQuery("SELECT `id`,`trackid`,`category`,`name`,`message`,`dt`,`time_worked`,`attachments`, `html` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` WHERE `id`='" . intval($this_id) . "' LIMIT 1");
  133. if (hesk_dbNumRows($res) != 1) {
  134. continue;
  135. }
  136. $row = hesk_dbFetchAssoc($res);
  137. /* Has this user access to the ticket category? */
  138. if (!hesk_okCategory($row['category'], 0)) {
  139. continue;
  140. }
  141. /* Insert ticket message as a new reply to target ticket */
  142. hesk_dbQuery("INSERT INTO `" . hesk_dbEscape($hesk_settings['db_pfix']) . "replies` (`replyto`,`name`,`message`,`dt`,`attachments`, `html`) VALUES ('" . intval($ticket['id']) . "','" . hesk_dbEscape($row['name']) . "','" . hesk_dbEscape($row['message']) . "','" . hesk_dbEscape($row['dt']) . "','" . hesk_dbEscape($row['attachments']) . "', '" . intval($row['html']) . "')");
  143. /* Update attachments */
  144. hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "attachments` SET `ticket_id`='" . hesk_dbEscape($ticket['trackid']) . "' WHERE `ticket_id`='" . hesk_dbEscape($row['trackid']) . "'");
  145. /* Get old ticket replies and insert them as new replies */
  146. $res = hesk_dbQuery("SELECT * FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "replies` WHERE `replyto`='" . intval($row['id']) . "' ORDER BY `id` ASC");
  147. while ($reply = hesk_dbFetchAssoc($res)) {
  148. hesk_dbQuery("INSERT INTO `" . hesk_dbEscape($hesk_settings['db_pfix']) . "replies` (`replyto`,`name`,`message`,`dt`,`attachments`,`staffid`,`rating`,`read`, `html`) VALUES ('" . intval($ticket['id']) . "','" . hesk_dbEscape($reply['name']) . "','" . hesk_dbEscape($reply['message']) . "','" . hesk_dbEscape($reply['dt']) . "','" . hesk_dbEscape($reply['attachments']) . "','" . intval($reply['staffid']) . "','" . intval($reply['rating']) . "','" . intval($reply['read']) . "', '" . intval($reply['html']) . "')");
  149. }
  150. /* Delete replies to the old ticket */
  151. hesk_dbQuery("DELETE FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "replies` WHERE `replyto`='" . intval($row['id']) . "'");
  152. /* Get old ticket notes and insert them as new notes */
  153. $res = hesk_dbQuery("SELECT * FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "notes` WHERE `ticket`='" . intval($row['id']) . "' ORDER BY `id` ASC");
  154. while ($note = hesk_dbFetchAssoc($res)) {
  155. hesk_dbQuery("INSERT INTO `" . hesk_dbEscape($hesk_settings['db_pfix']) . "notes` (`ticket`,`who`,`dt`,`message`,`attachments`) VALUES ('" . intval($ticket['id']) . "','" . intval($note['who']) . "','" . hesk_dbEscape($note['dt']) . "','" . hesk_dbEscape($note['message']) . "','" . hesk_dbEscape($note['attachments']) . "')");
  156. }
  157. /* Delete replies to the old ticket */
  158. hesk_dbQuery("DELETE FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "notes` WHERE `ticket`='" . intval($row['id']) . "'");
  159. /* Delete old ticket */
  160. hesk_dbQuery("DELETE FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` WHERE `id`='" . intval($row['id']) . "'");
  161. /* Log that ticket has been merged */
  162. $history .= sprintf($hesklang['thist13'], hesk_date(), $row['trackid'], $_SESSION['name'] . ' (' . $_SESSION['user'] . ')');
  163. /* Add old ticket ID to target ticket "merged" field */
  164. $merged .= '#' . $row['trackid'];
  165. /* Convert old ticket "time worked" to seconds and add to $sec_worked variable */
  166. list ($hr, $min, $sec) = explode(':', $row['time_worked']);
  167. $sec_worked += (((int)$hr) * 3600) + (((int)$min) * 60) + ((int)$sec);
  168. }
  169. /* Convert seconds to HHH:MM:SS */
  170. $sec_worked = hesk_getTime('0:' . $sec_worked);
  171. // Get number of replies
  172. $total = 0;
  173. $staffreplies = 0;
  174. $res = hesk_dbQuery("SELECT COUNT(*) as `cnt`, `staffid` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "replies` WHERE `replyto`=" . intval($ticket['id']) . " GROUP BY CASE WHEN `staffid` = 0 THEN 0 ELSE 1 END ASC");
  175. while ($row = hesk_dbFetchAssoc($res)) {
  176. $total += $row['cnt'];
  177. $staffreplies += ($row['staffid'] ? $row['cnt'] : 0);
  178. }
  179. $replies_sql = " `replies`={$total}, `staffreplies`={$staffreplies} , ";
  180. // Get first staff reply
  181. if ($staffreplies) {
  182. $res = hesk_dbQuery("SELECT `dt`, `staffid` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "replies` WHERE `replyto`=" . intval($ticket['id']) . " AND `staffid`>0 ORDER BY `dt` ASC LIMIT 1");
  183. $reply = hesk_dbFetchAssoc($res);
  184. $replies_sql .= " `firstreply`='" . hesk_dbEscape($reply['dt']) . "', `firstreplyby`=" . intval($reply['staffid']) . " , ";
  185. }
  186. /* Update history (log) and merged IDs of target ticket */
  187. hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` SET $replies_sql `time_worked`=ADDTIME(`time_worked`, '" . hesk_dbEscape($sec_worked) . "'), `merged`=CONCAT(`merged`,'" . hesk_dbEscape($merged . '#') . "'), `history`=CONCAT(`history`,'" . hesk_dbEscape($history) . "') WHERE `id`='" . intval($merge_into) . "'");
  188. return true;
  189. } // END hesk_mergeTickets()
  190. function hesk_updateStaffDefaults()
  191. {
  192. global $hesk_settings, $hesklang;
  193. // Demo mode
  194. if (defined('HESK_DEMO')) {
  195. return true;
  196. }
  197. // Remove the part that forces saving as default - we don't need it every time
  198. $default_list = str_replace('&def=1', '', $_SERVER['QUERY_STRING']);
  199. // Update database
  200. $res = hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` SET `default_list`='" . hesk_dbEscape($default_list) . "' WHERE `id`='" . intval($_SESSION['id']) . "'");
  201. // Update session values so the changes take effect immediately
  202. $_SESSION['default_list'] = $default_list;
  203. return true;
  204. } // END hesk_updateStaffDefaults()
  205. function hesk_makeJsString($in)
  206. {
  207. return addslashes(preg_replace("/\s+/", ' ', $in));
  208. } // END hesk_makeJsString()
  209. function hesk_checkNewMail()
  210. {
  211. global $hesk_settings, $hesklang;
  212. $res = hesk_dbQuery("SELECT COUNT(*) FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "mail` WHERE `to`='" . intval($_SESSION['id']) . "' AND `read`='0' AND `deletedby`!='" . intval($_SESSION['id']) . "' ");
  213. $num = hesk_dbResult($res, 0, 0);
  214. return $num;
  215. } // END hesk_checkNewMail()
  216. function hesk_getCategoriesArray($kb = 0)
  217. {
  218. global $hesk_settings, $hesklang, $hesk_db_link;
  219. $categories = array();
  220. if ($kb) {
  221. $result = hesk_dbQuery('SELECT `id`, `name` FROM `' . hesk_dbEscape($hesk_settings['db_pfix']) . 'kb_categories` ORDER BY `cat_order` ASC');
  222. } else {
  223. $result = hesk_dbQuery('SELECT `id`, `name` FROM `' . hesk_dbEscape($hesk_settings['db_pfix']) . 'categories` ORDER BY `cat_order` ASC');
  224. }
  225. while ($row = hesk_dbFetchAssoc($result)) {
  226. $categories[$row['id']] = $row['name'];
  227. }
  228. return $categories;
  229. } // END hesk_getCategoriesArray()
  230. function hesk_getHTML($in)
  231. {
  232. global $hesk_settings, $hesklang;
  233. $replace_from = array("\t", "<?", "?>", "$", "<%", "%>");
  234. $replace_to = array("", "&lt;?", "?&gt;", "\$", "&lt;%", "%&gt;");
  235. $in = trim($in);
  236. $in = str_replace($replace_from, $replace_to, $in);
  237. $in = preg_replace('/\<script(.*)\>(.*)\<\/script\>/Uis', "<script$1></script>", $in);
  238. $in = preg_replace('/\<\!\-\-(.*)\-\-\>/Uis', "<!-- comments have been removed -->", $in);
  239. if (HESK_SLASH === true) {
  240. $in = addslashes($in);
  241. }
  242. $in = str_replace('\"', '"', $in);
  243. return $in;
  244. } // END hesk_getHTML()
  245. function hesk_activeSessionValidate($username, $password_hash, $tag)
  246. {
  247. // Salt and hash need to be separated by a |
  248. if (!strpos($tag, '|')) {
  249. return false;
  250. }
  251. // Get two parts of the tag
  252. list($salt, $hash) = explode('|', $tag, 2);
  253. // Make sure the hash matches existing username and password
  254. if ($hash == sha1($salt . strtolower($username) . $password_hash)) {
  255. return true;
  256. }
  257. return false;
  258. } // hesk_activeSessionValidate
  259. function hesk_activeSessionCreateTag($username, $password_hash)
  260. {
  261. $salt = uniqid(mt_rand(), true);
  262. return $salt . '|' . sha1($salt . strtolower($username) . $password_hash);
  263. } // END hesk_activeSessionCreateTag()
  264. function hesk_autoLogin($noredirect = 0)
  265. {
  266. global $hesk_settings, $hesklang, $hesk_db_link;
  267. if (!$hesk_settings['autologin']) {
  268. return false;
  269. }
  270. $user = hesk_htmlspecialchars(hesk_COOKIE('hesk_username'));
  271. $hash = hesk_htmlspecialchars(hesk_COOKIE('hesk_p'));
  272. define('HESK_USER', $user);
  273. if (empty($user) || empty($hash)) {
  274. return false;
  275. }
  276. /* Login cookies exist, now lets limit brute force attempts */
  277. hesk_limitBfAttempts();
  278. // Admin login URL
  279. $url = $hesk_settings['hesk_url'] . '/' . $hesk_settings['admin_dir'] . '/index.php?a=login&notice=1';
  280. /* Check username */
  281. $result = hesk_dbQuery('SELECT * FROM `' . $hesk_settings['db_pfix'] . "users` WHERE `user` = '" . hesk_dbEscape($user) . "' LIMIT 1");
  282. if (hesk_dbNumRows($result) != 1) {
  283. hesk_setcookie('hesk_username', '');
  284. hesk_setcookie('hesk_p', '');
  285. header('Location: '.$url);
  286. exit();
  287. }
  288. $res = hesk_dbFetchAssoc($result);
  289. /* Check password */
  290. if ($hash != hesk_Pass2Hash($res['pass'] . strtolower($user) . $res['pass'])) {
  291. hesk_setcookie('hesk_username', '');
  292. hesk_setcookie('hesk_p', '');
  293. header('Location: '.$url);
  294. exit();
  295. }
  296. // Set user details
  297. foreach ($res as $k => $v) {
  298. $_SESSION[$k] = $v;
  299. }
  300. /* Check if default password */
  301. if ($_SESSION['pass'] == '499d74967b28a841c98bb4baaabaad699ff3c079') {
  302. hesk_process_messages($hesklang['chdp'], 'NOREDIRECT', 'NOTICE');
  303. }
  304. // Set a tag that will be used to expire sessions after username or password change
  305. $_SESSION['session_verify'] = hesk_activeSessionCreateTag($user, $_SESSION['pass']);
  306. // We don't need the password hash anymore
  307. unset($_SESSION['pass']);
  308. /* Login successful, clean brute force attempts */
  309. hesk_cleanBfAttempts();
  310. /* Regenerate session ID (security) */
  311. hesk_session_regenerate_id();
  312. /* Get allowed categories */
  313. if (empty($_SESSION['isadmin'])) {
  314. $_SESSION['categories'] = explode(',', $_SESSION['categories']);
  315. }
  316. /* Renew cookies */
  317. hesk_setcookie('hesk_username', "$user", strtotime('+1 year'));
  318. hesk_setcookie('hesk_p', "$hash", strtotime('+1 year'));
  319. /* Close any old tickets here so Cron jobs aren't necessary */
  320. if ($hesk_settings['autoclose']) {
  321. $revision = sprintf($hesklang['thist3'], hesk_date(), $hesklang['auto']);
  322. $dt = date('Y-m-d H:i:s', time() - $hesk_settings['autoclose'] * 86400);
  323. // Notify customer of closed ticket?
  324. if ($hesk_settings['notify_closed']) {
  325. // Get list of tickets
  326. $result = hesk_dbQuery("SELECT * FROM `" . $hesk_settings['db_pfix'] . "tickets` WHERE `status` = '2' AND `lastchange` <= '" . hesk_dbEscape($dt) . "' ");
  327. if (hesk_dbNumRows($result) > 0) {
  328. global $ticket;
  329. // Load required functions?
  330. if (!function_exists('hesk_notifyCustomer')) {
  331. require(HESK_PATH . 'inc/email_functions.inc.php');
  332. }
  333. while ($ticket = hesk_dbFetchAssoc($result)) {
  334. $ticket['dt'] = hesk_date($ticket['dt'], true);
  335. $ticket['lastchange'] = hesk_date($ticket['lastchange'], true);
  336. $ticket = hesk_ticketToPlain($ticket, 1, 0);
  337. $modsForHesk_settings = mfh_getSettings();
  338. hesk_notifyCustomer($modsForHesk_settings, 'ticket_closed');
  339. }
  340. }
  341. }
  342. // Update ticket statuses and history in database
  343. hesk_dbQuery("UPDATE `" . $hesk_settings['db_pfix'] . "tickets` SET `status`='3', `closedat`=NOW(), `closedby`='-1', `history`=CONCAT(`history`,'" . hesk_dbEscape($revision) . "') WHERE `status` = '2' AND `lastchange` <= '" . hesk_dbEscape($dt) . "' ");
  344. }
  345. /* If session expired while a HESK page is open just continue using it, don't redirect */
  346. if ($noredirect) {
  347. return true;
  348. }
  349. /* Redirect to the destination page */
  350. header('Location: ' . hesk_verifyGoto());
  351. exit();
  352. } // END hesk_autoLogin()
  353. function hesk_isLoggedIn()
  354. {
  355. global $hesk_settings;
  356. $referer = hesk_input($_SERVER['REQUEST_URI']);
  357. $referer = str_replace('&amp;', '&', $referer);
  358. // Admin login URL
  359. $url = $hesk_settings['hesk_url'] . '/' . $hesk_settings['admin_dir'] . '/index.php?a=login&notice=1&goto='.urlencode($referer);
  360. if (empty($_SESSION['id']) || empty($_SESSION['session_verify'])) {
  361. if ($hesk_settings['autologin'] && hesk_autoLogin(1)) {
  362. // Users online
  363. if ($hesk_settings['online']) {
  364. require(HESK_PATH . 'inc/users_online.inc.php');
  365. hesk_initOnline($_SESSION['id']);
  366. }
  367. return true;
  368. }
  369. hesk_session_stop();
  370. header('Location: ' . $url);
  371. exit();
  372. } else {
  373. hesk_session_regenerate_id();
  374. // Let's make sure access data is up-to-date
  375. $res = hesk_dbQuery("SELECT `user`, `pass`, `isadmin`, `categories`, `heskprivileges` FROM `" . $hesk_settings['db_pfix'] . "users` WHERE `id` = '" . intval($_SESSION['id']) . "' LIMIT 1");
  376. // Exit if user not found
  377. if (hesk_dbNumRows($res) != 1) {
  378. hesk_session_stop();
  379. header('Location: ' . $url);
  380. exit();
  381. }
  382. // Fetch results from database
  383. $me = hesk_dbFetchAssoc($res);
  384. // Verify this session is still valid
  385. if (!hesk_activeSessionValidate($me['user'], $me['pass'], $_SESSION['session_verify'])) {
  386. hesk_session_stop();
  387. header('Location: ' . $url);
  388. exit();
  389. }
  390. // Update session variables as needed
  391. if ($me['isadmin'] == 1) {
  392. $_SESSION['isadmin'] = 1;
  393. } else {
  394. $_SESSION['isadmin'] = 0;
  395. $_SESSION['categories'] = explode(',', $me['categories']);
  396. $_SESSION['heskprivileges'] = $me['heskprivileges'];
  397. }
  398. // Users online
  399. if ($hesk_settings['online']) {
  400. require(HESK_PATH . 'inc/users_online.inc.php');
  401. hesk_initOnline($_SESSION['id']);
  402. }
  403. return true;
  404. }
  405. } // END hesk_isLoggedIn()
  406. function hesk_verifyGoto()
  407. {
  408. // Default redirect URL
  409. $url_default = 'admin_main.php';
  410. // If no "goto" parameter is set, redirect to the default page
  411. if (!hesk_isREQUEST('goto')) {
  412. return $url_default;
  413. }
  414. // Get the "goto" parameter
  415. $url = hesk_REQUEST('goto');
  416. // Fix encoded "&"
  417. $url = str_replace('&amp;', '&', $url);
  418. // Parse the URL for verification
  419. $url_parts = parse_url($url);
  420. // The "path" part is required
  421. if (!isset($url_parts['path'])) {
  422. return $url_default;
  423. }
  424. // Extract the file name from path
  425. $url = basename($url_parts['path']);
  426. // Allowed files for redirect
  427. $OK_urls = array(
  428. 'admin_main.php' => '',
  429. 'admin_settings.php' => '',
  430. 'admin_settings_save.php' => 'admin_settings.php',
  431. 'admin_ticket.php' => '',
  432. 'archive.php' => '',
  433. 'assign_owner.php' => '',
  434. 'banned_emails.php' => '',
  435. 'banned_ips.php' => '',
  436. 'change_status.php' => '',
  437. 'custom_fields.php' => '',
  438. 'custom_statuses.php' => '',
  439. 'edit_post.php' => '',
  440. 'email_templates.php' => '',
  441. 'export.php' => '',
  442. 'find_tickets.php' => '',
  443. 'generate_spam_question.php' => '',
  444. 'knowledgebase_private.php' => '',
  445. 'lock.php' => '',
  446. 'mail.php' => '',
  447. 'mail.php?a=read&id=1' => '',
  448. 'manage_canned.php' => '',
  449. 'manage_categories.php' => '',
  450. 'manage_knowledgebase.php' => '',
  451. 'manage_ticket_templates.php' => '',
  452. 'manage_users.php' => '',
  453. 'new_ticket.php' => '',
  454. 'profile.php' => '',
  455. 'reports.php' => '',
  456. 'service_messages.php' => '',
  457. 'show_tickets.php' => '',
  458. );
  459. // URL must match one of the allowed ones
  460. if (!isset($OK_urls[$url])) {
  461. return $url_default;
  462. }
  463. // Modify redirect?
  464. if (strlen($OK_urls[$url])) {
  465. $url = $OK_urls[$url];
  466. }
  467. // All OK, return the URL with query if set
  468. return isset($url_parts['query']) ? $url . '?' . $url_parts['query'] : $url;
  469. } // END hesk_verifyGoto()
  470. function hesk_Pass2Hash($plaintext)
  471. {
  472. $majorsalt = '';
  473. $len = strlen($plaintext);
  474. for ($i = 0; $i < $len; $i++) {
  475. $majorsalt .= sha1(substr($plaintext, $i, 1));
  476. }
  477. $corehash = sha1($majorsalt);
  478. return $corehash;
  479. } // END hesk_Pass2Hash()
  480. function hesk_formatDate($dt, $from_database = true)
  481. {
  482. $dt = hesk_date($dt, $from_database);
  483. $dt = str_replace(' ', '<br />', $dt);
  484. return $dt;
  485. } // End hesk_formatDate()
  486. function hesk_jsString($str)
  487. {
  488. $str = addslashes($str);
  489. $str = str_replace('<br />' , '' , $str);
  490. $from = array("/\r\n|\n|\r/", '/\<a href="mailto\:([^"]*)"\>([^\<]*)\<\/a\>/i', '/\<a href="([^"]*)" target="_blank"\>([^\<]*)\<\/a\>/i');
  491. $to = array("\\r\\n' + \r\n'", "$1", "$1");
  492. return preg_replace($from, $to, $str);
  493. } // END hesk_jsString()
  494. function hesk_myCategories($what = 'category')
  495. {
  496. if (!empty($_SESSION['isadmin'])) {
  497. return '1';
  498. } else {
  499. return " `" . hesk_dbEscape($what) . "` IN ('" . implode("','", array_map('intval', $_SESSION['categories'])) . "')";
  500. }
  501. } // END hesk_myCategories()
  502. function hesk_okCategory($cat, $error = 1, $user_isadmin = false, $user_cat = false)
  503. {
  504. global $hesklang;
  505. /* Checking for current user or someone else? */
  506. if ($user_isadmin === false) {
  507. $user_isadmin = $_SESSION['isadmin'];
  508. }
  509. if ($user_cat === false) {
  510. $user_cat = $_SESSION['categories'];
  511. }
  512. /* Is admin? */
  513. if ($user_isadmin) {
  514. return true;
  515. } /* Staff with access? */
  516. elseif (in_array($cat, $user_cat)) {
  517. return true;
  518. } /* No access */
  519. else {
  520. if ($error) {
  521. hesk_error($hesklang['not_authorized_tickets']);
  522. } else {
  523. return false;
  524. }
  525. }
  526. } // END hesk_okCategory()
  527. function hesk_checkPermission($feature, $showerror = 1)
  528. {
  529. global $hesklang;
  530. /* Admins have full access to all features */
  531. if (isset($_SESSION['isadmin']) && $_SESSION['isadmin']) {
  532. return true;
  533. }
  534. /* Check other staff for permissions */
  535. if (isset($_SESSION['heskprivileges']) && strpos($_SESSION['heskprivileges'], $feature) === false) {
  536. if ($showerror) {
  537. hesk_error($hesklang['no_permission'] . '<p>&nbsp;</p><p align="center"><a href="index.php">' . $hesklang['click_login'] . '</a>');
  538. } else {
  539. return false;
  540. }
  541. } else {
  542. return true;
  543. }
  544. } // END hesk_checkPermission()
  545. function hesk_purge_cache($type = '', $expire_after_seconds = 0)
  546. {
  547. global $hesk_settings;
  548. $cache_dir = dirname(dirname(__FILE__)).'/'.$hesk_settings['cache_dir'].'/';
  549. if ( ! is_dir($cache_dir))
  550. {
  551. return false;
  552. }
  553. switch ($type)
  554. {
  555. case 'export':
  556. $files = glob($cache_dir.'hesk_export_*', GLOB_NOSORT);
  557. break;
  558. case 'status':
  559. $files = glob($cache_dir.'status_*', GLOB_NOSORT);
  560. break;
  561. case 'cf':
  562. $files = glob($cache_dir.'cf_*', GLOB_NOSORT);
  563. break;
  564. case 'kb':
  565. $files = array($cache_dir.'kb.cache.php');
  566. break;
  567. default:
  568. hesk_rrmdir(trim($cache_dir, '/'), true);
  569. return true;
  570. }
  571. if (is_array($files))
  572. {
  573. array_walk($files, 'hesk_unlink_callable', $expire_after_seconds);
  574. }
  575. return true;
  576. } // END hesk_purge_cache()
  577. function hesk_rrmdir($dir, $keep_top_level=false)
  578. {
  579. $files = $keep_top_level ? array_diff(scandir($dir), array('.','..','index.htm')) : array_diff(scandir($dir), array('.','..'));
  580. foreach ($files as $file)
  581. {
  582. (is_dir("$dir/$file")) ? hesk_rrmdir("$dir/$file") : @unlink("$dir/$file");
  583. }
  584. return $keep_top_level ? true : @rmdir($dir);
  585. } // END hesk_rrmdir()