PageRenderTime 27ms CodeModel.GetById 11ms RepoModel.GetById 1ms app.codeStats 0ms

/inc/common.inc.php

https://gitlab.com/kingcody/Mods-for-HESK
PHP | 1565 lines | 1112 code | 305 blank | 148 comment | 178 complexity | 242d396011839ef09a02d52474b9700c MD5 | raw file
  1. <?php
  2. /*******************************************************************************
  3. * Title: Help Desk Software HESK
  4. * Version: 2.6.7 from 18th April 2016
  5. * Author: Klemen Stirn
  6. * Website: http://www.hesk.com
  7. ********************************************************************************
  8. * COPYRIGHT AND TRADEMARK NOTICE
  9. * Copyright 2005-2015 Klemen Stirn. All Rights Reserved.
  10. * HESK is a registered trademark of Klemen Stirn.
  11. * The HESK may be used and modified free of charge by anyone
  12. * AS LONG AS COPYRIGHT NOTICES AND ALL THE COMMENTS REMAIN INTACT.
  13. * By using this code you agree to indemnify Klemen Stirn from any
  14. * liability that might arise from it's use.
  15. * Selling the code for this program, in part or full, without prior
  16. * written consent is expressly forbidden.
  17. * Using this code, in part or full, to create derivate work,
  18. * new scripts or products is expressly forbidden. Obtain permission
  19. * before redistributing this software over the Internet or in
  20. * any other medium. In all cases copyright and header must remain intact.
  21. * This Copyright is in full effect in any country that has International
  22. * Trade Agreements with the United States of America or
  23. * with the European Union.
  24. * Removing any of the copyright notices without purchasing a license
  25. * is expressly forbidden. To remove HESK copyright notice you must purchase
  26. * a license for this script. For more information on how to obtain
  27. * a license please visit the page below:
  28. * https://www.hesk.com/buy.php
  29. *******************************************************************************/
  30. /* Check if this is a valid include */
  31. if (!defined('IN_SCRIPT')) {
  32. die('Invalid attempt');
  33. }
  34. #error_reporting(E_ALL);
  35. // Set correct Content-Type header
  36. if (!defined('NO_HTTP_HEADER')) {
  37. header('Content-Type: text/html; charset=utf-8');
  38. }
  39. // Set backslash options
  40. if (get_magic_quotes_gpc()) {
  41. define('HESK_SLASH', false);
  42. } else {
  43. define('HESK_SLASH', true);
  44. }
  45. // Define some constants for backward-compatibility
  46. if (!defined('ENT_SUBSTITUTE')) {
  47. define('ENT_SUBSTITUTE', 0);
  48. }
  49. if (!defined('ENT_XHTML')) {
  50. define('ENT_XHTML', 0);
  51. }
  52. // Load language file
  53. hesk_getLanguage();
  54. /*** FUNCTIONS ***/
  55. function hesk_service_message($sm)
  56. {
  57. $faIcon = $sm['icon'];
  58. switch ($sm['style']) {
  59. case 1:
  60. $style = "alert alert-success";
  61. break;
  62. case 2:
  63. $style = "alert alert-info";
  64. break;
  65. case 3:
  66. $style = "alert alert-warning";
  67. break;
  68. case 4:
  69. $style = "alert alert-danger";
  70. break;
  71. default:
  72. $style = "none";
  73. }
  74. ?>
  75. <div class="<?php echo $style; ?>">
  76. <?php echo $faIcon == '' ? '' : '<i class="' . $faIcon . '"></i> '; ?>
  77. <b><?php echo $sm['title']; ?></b><?php echo $sm['message']; ?>
  78. </div>
  79. <br/>
  80. <?php
  81. } // END hesk_service_message()
  82. function hesk_isBannedIP($ip)
  83. {
  84. global $hesk_settings, $hesklang, $hesk_db_link;
  85. $ip = ip2long($ip) or $ip = 0;
  86. // We need positive value of IP
  87. if ($ip < 0) {
  88. $ip += 4294967296;
  89. } elseif ($ip > 4294967296) {
  90. $ip = 4294967296;
  91. }
  92. $res = hesk_dbQuery("SELECT `id` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "banned_ips` WHERE {$ip} BETWEEN `ip_from` AND `ip_to` LIMIT 1");
  93. return (hesk_dbNumRows($res) == 1) ? hesk_dbResult($res) : false;
  94. } // END hesk_isBannedIP()
  95. function hesk_isBannedEmail($email)
  96. {
  97. global $hesk_settings, $hesklang, $hesk_db_link;
  98. $email = strtolower($email);
  99. $res = hesk_dbQuery("SELECT `id` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "banned_emails` WHERE `email` IN ('" . hesk_dbEscape($email) . "', '" . hesk_dbEscape(substr($email, strrpos($email, "@"))) . "') LIMIT 1");
  100. return (hesk_dbNumRows($res) == 1) ? hesk_dbResult($res) : false;
  101. } // END hesk_isBannedEmail()
  102. function hesk_clean_utf8($in)
  103. {
  104. //reject overly long 2 byte sequences, as well as characters above U+10000 and replace with ?
  105. $in = preg_replace('/[\x00-\x08\x10\x0B\x0C\x0E-\x19\x7F]' .
  106. '|[\x00-\x7F][\x80-\xBF]+' .
  107. '|([\xC0\xC1]|[\xF0-\xFF])[\x80-\xBF]*' .
  108. '|[\xC2-\xDF]((?![\x80-\xBF])|[\x80-\xBF]{2,})' .
  109. '|[\xE0-\xEF](([\x80-\xBF](?![\x80-\xBF]))|(?![\x80-\xBF]{2})|[\x80-\xBF]{3,})/S',
  110. '?', $in);
  111. //reject overly long 3 byte sequences and UTF-16 surrogates and replace with ?
  112. $in = preg_replace('/\xE0[\x80-\x9F][\x80-\xBF]' .
  113. '|\xED[\xA0-\xBF][\x80-\xBF]/S', '?', $in);
  114. return $in;
  115. } // END hesk_clean_utf8()
  116. function hesk_load_database_functions()
  117. {
  118. // Preferrably use the MySQLi functions
  119. if (function_exists('mysqli_connect')) {
  120. require(HESK_PATH . 'inc/database_mysqli.inc.php');
  121. } // Default to MySQL
  122. else {
  123. require(HESK_PATH . 'inc/database.inc.php');
  124. }
  125. } // END hesk_load_database_functions()
  126. function hesk_load_api_database_functions()
  127. {
  128. require(HESK_PATH . 'api/core/json_error.php');
  129. // Preferrably use the MySQLi functions
  130. if (function_exists('mysqli_connect')) {
  131. require(HESK_PATH . 'api/core/database_mysqli.inc.php');
  132. } // Default to MySQL
  133. else {
  134. require(HESK_PATH . 'api/core/database.inc.php');
  135. }
  136. } // END hesk_load_database_functions()
  137. function hesk_load_internal_api_database_functions()
  138. {
  139. require(HESK_PATH . 'internal-api/core/json_error.php');
  140. // Preferrably use the MySQLi functions
  141. if (function_exists('mysqli_connect')) {
  142. require(HESK_PATH . 'internal-api/core/database_mysqli.inc.php');
  143. } // Default to MySQL
  144. else {
  145. require(HESK_PATH . 'internal-api/core/database.inc.php');
  146. }
  147. } // END hesk_load_database_functions()
  148. function hesk_load_cron_database_functions()
  149. {
  150. if (function_exists('mysqli_connect')) {
  151. require(HESK_PATH . 'cron/core/database_mysqli.inc.php');
  152. } // Default to MySQL
  153. else {
  154. require(HESK_PATH . 'cron/core/database.inc.php');
  155. }
  156. } // END hesk_load_cron_database_functions()
  157. function hesk_unlink($file, $older_than = 0)
  158. {
  159. return (is_file($file) && (!$older_than || (time() - filectime($file)) > $older_than) && @unlink($file)) ? true : false;
  160. } // END hesk_unlink()
  161. function hesk_utf8_urldecode($in)
  162. {
  163. $in = preg_replace("/%u([0-9a-f]{3,4})/i", "&#x\\1;", urldecode($in));
  164. return hesk_html_entity_decode($in);
  165. } // END hesk_utf8_urldecode
  166. function hesk_SESSION($in, $default = '')
  167. {
  168. return isset($_SESSION[$in]) && ! is_array($_SESSION[$in]) ? $_SESSION[$in] : $default;
  169. } // END hesk_SESSION();
  170. function hesk_COOKIE($in, $default = '')
  171. {
  172. return isset($_COOKIE[$in]) && !is_array($_COOKIE[$in]) ? $_COOKIE[$in] : $default;
  173. } // END hesk_COOKIE();
  174. function hesk_GET($in, $default = '')
  175. {
  176. return isset($_GET[$in]) && !is_array($_GET[$in]) ? $_GET[$in] : $default;
  177. } // END hesk_GET()
  178. function hesk_POST($in, $default = '')
  179. {
  180. return isset($_POST[$in]) && !is_array($_POST[$in]) ? $_POST[$in] : $default;
  181. } // END hesk_POST()
  182. function hesk_POST_array($in, $default = array())
  183. {
  184. return isset($_POST[$in]) && is_array($_POST[$in]) ? $_POST[$in] : $default;
  185. } // END hesk_POST_array()
  186. function hesk_REQUEST($in, $default = false)
  187. {
  188. return isset($_GET[$in]) ? hesk_input(hesk_GET($in)) : (isset($_POST[$in]) ? hesk_input(hesk_POST($in)) : $default);
  189. } // END hesk_REQUEST()
  190. function hesk_isREQUEST($in)
  191. {
  192. return isset($_GET[$in]) || isset($_POST[$in]) ? true : false;
  193. } // END hesk_isREQUEST()
  194. function hesk_htmlspecialchars_decode($in)
  195. {
  196. return str_replace(array('&amp;', '&lt;', '&gt;', '&quot;'), array('&', '<', '>', '"'), $in);
  197. } // END hesk_htmlspecialchars_decode()
  198. function hesk_html_entity_decode($in)
  199. {
  200. return html_entity_decode($in, ENT_COMPAT | ENT_XHTML, 'UTF-8');
  201. #return html_entity_decode($in, ENT_COMPAT | ENT_XHTML, 'ISO-8859-1');
  202. } // END hesk_html_entity_decode()
  203. function hesk_htmlspecialchars($in)
  204. {
  205. return htmlspecialchars($in, ENT_COMPAT | ENT_SUBSTITUTE | ENT_XHTML, 'UTF-8');
  206. #return htmlspecialchars($in, ENT_COMPAT | ENT_SUBSTITUTE | ENT_XHTML, 'ISO-8859-1');
  207. } // END hesk_htmlspecialchars()
  208. function hesk_htmlentities($in)
  209. {
  210. return htmlentities($in, ENT_COMPAT | ENT_SUBSTITUTE | ENT_XHTML, 'UTF-8');
  211. #return htmlentities($in, ENT_COMPAT | ENT_SUBSTITUTE | ENT_XHTML, 'ISO-8859-1');
  212. } // END hesk_htmlentities()
  213. function hesk_slashJS($in)
  214. {
  215. return str_replace('\'', '\\\'', $in);
  216. } // END hesk_slashJS()
  217. function hesk_verifyEmailMatch($trackingID, $my_email = 0, $ticket_email = 0, $error = 1)
  218. {
  219. global $hesk_settings, $hesklang, $hesk_db_link;
  220. /* Email required to view ticket? */
  221. if (!$hesk_settings['email_view_ticket']) {
  222. $hesk_settings['e_param'] = '';
  223. $hesk_settings['e_query'] = '';
  224. $hesk_settings['e_email'] = '';
  225. return true;
  226. }
  227. /* Limit brute force attempts */
  228. hesk_limitBfAttempts();
  229. /* Get email address */
  230. if ($my_email) {
  231. $hesk_settings['e_param'] = '&e=' . rawurlencode($my_email);
  232. $hesk_settings['e_query'] = '&amp;e=' . rawurlencode($my_email);
  233. $hesk_settings['e_email'] = $my_email;
  234. } else {
  235. $my_email = hesk_getCustomerEmail();
  236. }
  237. /* Get email from ticket */
  238. if (!$ticket_email) {
  239. $res = hesk_dbQuery("SELECT `email` FROM `" . $hesk_settings['db_pfix'] . "tickets` WHERE `trackid`='" . hesk_dbEscape($trackingID) . "' LIMIT 1");
  240. if (hesk_dbNumRows($res) == 1) {
  241. $ticket_email = hesk_dbResult($res);
  242. } else {
  243. hesk_process_messages($hesklang['ticket_not_found'], 'ticket.php');
  244. }
  245. }
  246. /* Validate email */
  247. if ($hesk_settings['multi_eml']) {
  248. $ticket_email = str_replace(';', ',', $ticket_email);
  249. $valid_emails = explode(',', strtolower($ticket_email));
  250. if (in_array(strtolower($my_email), $valid_emails)) {
  251. /* Match, clean brute force attempts and return true */
  252. hesk_cleanBfAttempts();
  253. return true;
  254. }
  255. } elseif (strtolower($ticket_email) == strtolower($my_email)) {
  256. /* Match, clean brute force attempts and return true */
  257. hesk_cleanBfAttempts();
  258. return true;
  259. }
  260. /* Email doesn't match, clean cookies and error out */
  261. if ($error) {
  262. setcookie('hesk_myemail', '');
  263. hesk_process_messages($hesklang['enmdb'], 'ticket.php?track=' . $trackingID . '&Refresh=' . rand(10000, 99999));
  264. } else {
  265. return false;
  266. }
  267. } // END hesk_verifyEmailMatch()
  268. function hesk_getCustomerEmail($can_remember = 0, $field = '')
  269. {
  270. global $hesk_settings, $hesklang;
  271. /* Email required to view ticket? */
  272. if (!$hesk_settings['email_view_ticket']) {
  273. $hesk_settings['e_param'] = '';
  274. $hesk_settings['e_query'] = '';
  275. $hesk_settings['e_email'] = '';
  276. return '';
  277. }
  278. /* Is this a form that enables remembering email? */
  279. if ($can_remember) {
  280. global $do_remember;
  281. }
  282. $my_email = '';
  283. /* Is email in session? */
  284. if ( strlen($field) && isset($_SESSION[$field]) )
  285. {
  286. $my_email = hesk_validateEmail($_SESSION[$field], 'ERR', 0);
  287. }
  288. /* Is email in query string? */
  289. if (isset($_GET['e']) || isset($_POST['e'])) {
  290. $my_email = hesk_validateEmail(hesk_REQUEST('e'), 'ERR', 0);
  291. } /* Is email in cookie? */
  292. elseif ( isset($_GET['e']) || isset($_POST['e']) ) {
  293. $my_email = hesk_validateEmail(hesk_COOKIE('hesk_myemail'), 'ERR', 0);
  294. if ($can_remember && $my_email) {
  295. $do_remember = ' checked="checked" ';
  296. }
  297. }
  298. $hesk_settings['e_param'] = '&e=' . rawurlencode($my_email);
  299. $hesk_settings['e_query'] = '&amp;e=' . rawurlencode($my_email);
  300. $hesk_settings['e_email'] = $my_email;
  301. return $my_email;
  302. } // END hesk_getCustomerEmail()
  303. function hesk_formatBytes($size, $translate_unit = 1, $precision = 2)
  304. {
  305. global $hesklang;
  306. $units = array(
  307. 'GB' => 1073741824,
  308. 'MB' => 1048576,
  309. 'kB' => 1024,
  310. 'B' => 1
  311. );
  312. foreach ($units as $suffix => $bytes) {
  313. if ($bytes > $size) {
  314. continue;
  315. }
  316. $full = $size / $bytes;
  317. $round = round($full, $precision);
  318. if ($full == $round) {
  319. if ($translate_unit) {
  320. return $round . ' ' . $hesklang[$suffix];
  321. } else {
  322. return $round . ' ' . $suffix;
  323. }
  324. }
  325. }
  326. return false;
  327. } // End hesk_formatBytes()
  328. function hesk_autoAssignTicket($ticket_category)
  329. {
  330. global $hesk_settings, $hesklang;
  331. /* Auto assign ticket enabled? */
  332. if (!$hesk_settings['autoassign']) {
  333. return false;
  334. }
  335. $autoassign_owner = array();
  336. /* Get all possible auto-assign staff, order by number of open tickets */
  337. $res = hesk_dbQuery("SELECT `t1`.`id`,`t1`.`user`,`t1`.`name`, `t1`.`email`, `t1`.`language`, `t1`.`isadmin`, `t1`.`categories`, `t1`.`notify_assigned`, `t1`.`heskprivileges`,
  338. (SELECT COUNT(*) FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` FORCE KEY (`statuses`) WHERE `owner`=`t1`.`id` AND `status` IN (SELECT `ID` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses` WHERE `IsClosed` = 0) ) as `open_tickets`
  339. FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` AS `t1`
  340. WHERE `t1`.`autoassign`='1' ORDER BY `open_tickets` ASC, RAND()");
  341. /* Loop through the rows and return the first appropriate one */
  342. while ($myuser = hesk_dbFetchAssoc($res)) {
  343. /* Is this an administrator? */
  344. if ($myuser['isadmin']) {
  345. $autoassign_owner = $myuser;
  346. $hesk_settings['user_data'][$myuser['id']] = $myuser;
  347. hesk_dbFreeResult($res);
  348. break;
  349. }
  350. /* Not and administrator, check two things: */
  351. /* --> can view and reply to tickets */
  352. if (strpos($myuser['heskprivileges'], 'can_view_tickets') === false || strpos($myuser['heskprivileges'], 'can_reply_tickets') === false) {
  353. continue;
  354. }
  355. /* --> has access to ticket category */
  356. $myuser['categories'] = explode(',', $myuser['categories']);
  357. if (in_array($ticket_category, $myuser['categories'])) {
  358. $autoassign_owner = $myuser;
  359. $hesk_settings['user_data'][$myuser['id']] = $myuser;
  360. hesk_dbFreeResult($res);
  361. break;
  362. }
  363. }
  364. return $autoassign_owner;
  365. } // END hesk_autoAssignTicket()
  366. function hesk_cleanID($field = 'track')
  367. {
  368. if ( isset($_SESSION[$field]) ) {
  369. return substr(preg_replace('/[^A-Z0-9\-]/', '', strtoupper($_SESSION[$field])), 0, 12);
  370. } elseif ( isset($_GET[$field]) && ! is_array($_GET[$field]) ) {
  371. return substr(preg_replace('/[^A-Z0-9\-]/', '', strtoupper($_GET[$field])), 0, 12);
  372. } elseif (isset($_POST[$field]) && !is_array($_POST[$field])) {
  373. return substr(preg_replace('/[^A-Z0-9\-]/', '', strtoupper($_POST[$field])), 0, 12);
  374. } else {
  375. return false;
  376. }
  377. } // END hesk_cleanID()
  378. function hesk_createID()
  379. {
  380. global $hesk_settings, $hesklang, $hesk_error_buffer;
  381. /*** Generate tracking ID and make sure it's not a duplicate one ***/
  382. /* Ticket ID can be of these chars */
  383. $useChars = 'AEUYBDGHJLMNPQRSTVWXZ123456789';
  384. /* Set tracking ID to an empty string */
  385. $trackingID = '';
  386. /* Let's avoid duplicate ticket ID's, try up to 3 times */
  387. for ($i = 1; $i <= 3; $i++) {
  388. /* Generate raw ID */
  389. $trackingID .= $useChars[mt_rand(0, 29)];
  390. $trackingID .= $useChars[mt_rand(0, 29)];
  391. $trackingID .= $useChars[mt_rand(0, 29)];
  392. $trackingID .= $useChars[mt_rand(0, 29)];
  393. $trackingID .= $useChars[mt_rand(0, 29)];
  394. $trackingID .= $useChars[mt_rand(0, 29)];
  395. $trackingID .= $useChars[mt_rand(0, 29)];
  396. $trackingID .= $useChars[mt_rand(0, 29)];
  397. $trackingID .= $useChars[mt_rand(0, 29)];
  398. $trackingID .= $useChars[mt_rand(0, 29)];
  399. /* Format the ID to the correct shape and check wording */
  400. $trackingID = hesk_formatID($trackingID);
  401. /* Check for duplicate IDs */
  402. $res = hesk_dbQuery("SELECT `id` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` WHERE `trackid` = '" . hesk_dbEscape($trackingID) . "' LIMIT 1");
  403. if (hesk_dbNumRows($res) == 0) {
  404. /* Everything is OK, no duplicates found */
  405. return $trackingID;
  406. }
  407. /* A duplicate ID has been found! Let's try again (up to 2 more) */
  408. $trackingID = '';
  409. }
  410. /* No valid tracking ID, try one more time with microtime() */
  411. $trackingID = $useChars[mt_rand(0, 29)];
  412. $trackingID .= $useChars[mt_rand(0, 29)];
  413. $trackingID .= $useChars[mt_rand(0, 29)];
  414. $trackingID .= $useChars[mt_rand(0, 29)];
  415. $trackingID .= $useChars[mt_rand(0, 29)];
  416. $trackingID .= substr(microtime(), -5);
  417. /* Format the ID to the correct shape and check wording */
  418. $trackingID = hesk_formatID($trackingID);
  419. $res = hesk_dbQuery("SELECT `id` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` WHERE `trackid` = '" . hesk_dbEscape($trackingID) . "' LIMIT 1");
  420. /* All failed, must be a server-side problem... */
  421. if (hesk_dbNumRows($res) == 0) {
  422. return $trackingID;
  423. }
  424. $hesk_error_buffer['etid'] = $hesklang['e_tid'];
  425. return false;
  426. } // END hesk_createID()
  427. function hesk_formatID($id)
  428. {
  429. $useChars = 'AEUYBDGHJLMNPQRSTVWXZ123456789';
  430. $replace = $useChars[mt_rand(0, 29)];
  431. $replace .= mt_rand(1, 9);
  432. $replace .= $useChars[mt_rand(0, 29)];
  433. /*
  434. Remove 3 letter bad words from ID
  435. Possiblitiy: 1:27,000
  436. */
  437. $remove = array(
  438. 'ASS',
  439. 'CUM',
  440. 'FAG',
  441. 'FUK',
  442. 'GAY',
  443. 'SEX',
  444. 'TIT',
  445. 'XXX',
  446. );
  447. $id = str_replace($remove, $replace, $id);
  448. /*
  449. Remove 4 letter bad words from ID
  450. Possiblitiy: 1:810,000
  451. */
  452. $remove = array(
  453. 'ANAL',
  454. 'ANUS',
  455. 'BUTT',
  456. 'CAWK',
  457. 'CLIT',
  458. 'COCK',
  459. 'CRAP',
  460. 'CUNT',
  461. 'DICK',
  462. 'DYKE',
  463. 'FART',
  464. 'FUCK',
  465. 'JAPS',
  466. 'JERK',
  467. 'JIZZ',
  468. 'KNOB',
  469. 'PISS',
  470. 'POOP',
  471. 'SHIT',
  472. 'SLUT',
  473. 'SUCK',
  474. 'TURD',
  475. // Also, remove words that are known to trigger mod_security
  476. 'WGET',
  477. );
  478. $replace .= mt_rand(1, 9);
  479. $id = str_replace($remove, $replace, $id);
  480. /* Format the ID string into XXX-XXX-XXXX format for easier readability */
  481. $id = $id[0] . $id[1] . $id[2] . '-' . $id[3] . $id[4] . $id[5] . '-' . $id[6] . $id[7] . $id[8] . $id[9];
  482. return $id;
  483. } // END hesk_formatID()
  484. function hesk_cleanBfAttempts()
  485. {
  486. global $hesk_settings, $hesklang;
  487. /* If this feature is disabled, just return */
  488. if (!$hesk_settings['attempt_limit'] || defined('HESK_BF_CLEAN')) {
  489. return true;
  490. }
  491. /* Delete expired logs from the database */
  492. $res = hesk_dbQuery("DELETE FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "logins` WHERE `ip`='" . hesk_dbEscape($_SERVER['REMOTE_ADDR']) . "'");
  493. define('HESK_BF_CLEAN', 1);
  494. return true;
  495. } // END hesk_cleanAttempts()
  496. function hesk_limitBfAttempts($showError = 1)
  497. {
  498. global $hesk_settings, $hesklang;
  499. // Check if this IP is banned permanently
  500. if (hesk_isBannedIP($_SERVER['REMOTE_ADDR'])) {
  501. hesk_error($hesklang['baned_ip'], 0);
  502. }
  503. /* If this feature is disabled or already called, return false */
  504. if (!$hesk_settings['attempt_limit'] || defined('HESK_BF_LIMIT')) {
  505. return false;
  506. }
  507. /* Define this constant to avoid duplicate checks */
  508. define('HESK_BF_LIMIT', 1);
  509. $ip = $_SERVER['REMOTE_ADDR'];
  510. /* Get number of failed attempts from the database */
  511. $res = hesk_dbQuery("SELECT `number`, (CASE WHEN `last_attempt` IS NOT NULL AND DATE_ADD(`last_attempt`, INTERVAL " . intval($hesk_settings['attempt_banmin']) . " MINUTE ) > NOW() THEN 1 ELSE 0 END) AS `banned` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "logins` WHERE `ip`='" . hesk_dbEscape($ip) . "' LIMIT 1");
  512. /* Not in the database yet? Add first one and return false */
  513. if (hesk_dbNumRows($res) != 1) {
  514. hesk_dbQuery("INSERT INTO `" . hesk_dbEscape($hesk_settings['db_pfix']) . "logins` (`ip`) VALUES ('" . hesk_dbEscape($ip) . "')");
  515. return false;
  516. }
  517. /* Get number of failed attempts and increase by 1 */
  518. $row = hesk_dbFetchAssoc($res);
  519. $row['number']++;
  520. /* If too many failed attempts either return error or reset count if time limit expired */
  521. if ($row['number'] >= $hesk_settings['attempt_limit']) {
  522. if ($row['banned']) {
  523. $tmp = sprintf($hesklang['yhbb'], $hesk_settings['attempt_banmin']);
  524. unset($_SESSION);
  525. if ($showError) {
  526. hesk_error($tmp, 0);
  527. } else {
  528. return $tmp;
  529. }
  530. } else {
  531. $row['number'] = 1;
  532. }
  533. }
  534. hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "logins` SET `number`=" . intval($row['number']) . " WHERE `ip`='" . hesk_dbEscape($ip) . "' LIMIT 1");
  535. return false;
  536. } // END hesk_limitAttempts()
  537. function hesk_getCategoryName($id)
  538. {
  539. global $hesk_settings, $hesklang;
  540. if (empty($id)) {
  541. return $hesklang['unas'];
  542. }
  543. // If we already have the name no need to query DB another time
  544. if (isset($hesk_settings['category_data'][$id]['name'])) {
  545. return $hesk_settings['category_data'][$id]['name'];
  546. }
  547. $res = hesk_dbQuery("SELECT `name` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "categories` WHERE `id`='" . intval($id) . "' LIMIT 1");
  548. if (hesk_dbNumRows($res) != 1) {
  549. return $hesklang['catd'];
  550. }
  551. $hesk_settings['category_data'][$id]['name'] = hesk_dbResult($res, 0, 0);
  552. return $hesk_settings['category_data'][$id]['name'];
  553. } // END hesk_getOwnerName()
  554. function hesk_getOwnerName($id)
  555. {
  556. global $hesk_settings, $hesklang;
  557. if (empty($id)) {
  558. return $hesklang['unas'];
  559. }
  560. // If we already have the name no need to query DB another time
  561. if (isset($hesk_settings['user_data'][$id]['name'])) {
  562. return $hesk_settings['user_data'][$id]['name'];
  563. }
  564. $res = hesk_dbQuery("SELECT `name` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` WHERE `id`='" . intval($id) . "' LIMIT 1");
  565. if (hesk_dbNumRows($res) != 1) {
  566. return $hesklang['unas'];
  567. }
  568. $hesk_settings['user_data'][$id]['name'] = hesk_dbResult($res, 0, 0);
  569. return $hesk_settings['user_data'][$id]['name'];
  570. } // END hesk_getOwnerName()
  571. function hesk_cleanSessionVars($arr)
  572. {
  573. if (is_array($arr)) {
  574. foreach ($arr as $str) {
  575. if (isset($_SESSION[$str])) {
  576. unset($_SESSION[$str]);
  577. }
  578. }
  579. } elseif (isset($_SESSION[$arr])) {
  580. unset($_SESSION[$arr]);
  581. }
  582. } // End hesk_cleanSessionVars()
  583. function hesk_process_messages($message, $redirect_to, $type = 'ERROR')
  584. {
  585. global $hesk_settings, $hesklang;
  586. switch ($type) {
  587. case 'SUCCESS':
  588. $_SESSION['HESK_SUCCESS'] = TRUE;
  589. break;
  590. case 'NOTICE':
  591. $_SESSION['HESK_NOTICE'] = TRUE;
  592. break;
  593. case 'INFO':
  594. $_SESSION['HESK_INFO'] = TRUE;
  595. break;
  596. default:
  597. $_SESSION['HESK_ERROR'] = TRUE;
  598. }
  599. $_SESSION['HESK_MESSAGE'] = $message;
  600. /* In some cases we don't want a redirect */
  601. if ($redirect_to == 'NOREDIRECT') {
  602. return TRUE;
  603. }
  604. header('Location: ' . $redirect_to);
  605. exit();
  606. } // END hesk_process_messages()
  607. function hesk_handle_messages()
  608. {
  609. global $hesk_settings, $hesklang;
  610. $return_value = true;
  611. // Primary message - only one can be displayed and HESK_MESSAGE is required
  612. if (isset($_SESSION['HESK_MESSAGE'])) {
  613. if (isset($_SESSION['HESK_SUCCESS'])) {
  614. hesk_show_success($_SESSION['HESK_MESSAGE']);
  615. } elseif (isset($_SESSION['HESK_ERROR'])) {
  616. hesk_show_error($_SESSION['HESK_MESSAGE']);
  617. $return_value = false;
  618. } elseif (isset($_SESSION['HESK_NOTICE'])) {
  619. hesk_show_notice($_SESSION['HESK_MESSAGE']);
  620. } elseif (isset($_SESSION['HESK_INFO'])) {
  621. hesk_show_info($_SESSION['HESK_MESSAGE']);
  622. }
  623. hesk_cleanSessionVars('HESK_MESSAGE');
  624. }
  625. // Cleanup any primary message types set
  626. hesk_cleanSessionVars('HESK_ERROR');
  627. hesk_cleanSessionVars('HESK_SUCCESS');
  628. hesk_cleanSessionVars('HESK_NOTICE');
  629. hesk_cleanSessionVars('HESK_INFO');
  630. // Secondary message
  631. if (isset($_SESSION['HESK_2ND_NOTICE']) && isset($_SESSION['HESK_2ND_MESSAGE'])) {
  632. hesk_show_notice($_SESSION['HESK_2ND_MESSAGE']);
  633. hesk_cleanSessionVars('HESK_2ND_NOTICE');
  634. hesk_cleanSessionVars('HESK_2ND_MESSAGE');
  635. }
  636. return $return_value;
  637. } // END hesk_handle_messages()
  638. function hesk_show_error($message, $title = '', $append_colon = true)
  639. {
  640. global $hesk_settings, $hesklang;
  641. $title = $title ? $title : $hesklang['error'];
  642. $title = $append_colon ? $title . ':' : $title;
  643. ?>
  644. <div align="left" class="alert alert-danger">
  645. <b><?php echo $title; ?></b> <?php echo $message; ?>
  646. </div>
  647. <?php
  648. } // END hesk_show_error()
  649. function hesk_show_success($message, $title = '', $append_colon = true)
  650. {
  651. global $hesk_settings, $hesklang;
  652. $title = $title ? $title : $hesklang['success'];
  653. $title = $append_colon ? $title . ':' : $title;
  654. ?>
  655. <div align="left" class="alert alert-success">
  656. <b><?php echo $title; ?></b> <?php echo $message; ?>
  657. </div>
  658. <?php
  659. } // END hesk_show_success()
  660. function hesk_show_notice($message, $title = '', $append_colon = true)
  661. {
  662. global $hesk_settings, $hesklang;
  663. $title = $title ? $title : $hesklang['note'];
  664. $title = $append_colon ? $title . ':' : $title;
  665. ?>
  666. <div class="alert alert-warning">
  667. <b><?php echo $title; ?></b> <?php echo $message; ?>
  668. </div>
  669. <?php
  670. } // END hesk_show_notice()
  671. function hesk_show_info($message, $title = '', $append_colon = true)
  672. {
  673. global $hesk_settings, $hesklang;
  674. $title = $title ? $title : $hesklang['info'];
  675. $title = $append_colon ? $title . ':' : $title;
  676. ?>
  677. <div class="info">
  678. <img src="<?php echo HESK_PATH; ?>img/info.png" width="16" height="16" border="0" alt=""
  679. style="vertical-align:text-bottom"/>
  680. <b><?php echo $title; ?></b> <?php echo $message; ?>
  681. </div>
  682. <br/>
  683. <?php
  684. } // END hesk_show_info()
  685. function hesk_token_echo($do_echo = 1)
  686. {
  687. if (!defined('SESSION_CLEAN')) {
  688. $_SESSION['token'] = hesk_htmlspecialchars(strip_tags($_SESSION['token']));
  689. define('SESSION_CLEAN', true);
  690. }
  691. if ($do_echo) {
  692. echo $_SESSION['token'];
  693. } else {
  694. return $_SESSION['token'];
  695. }
  696. } // END hesk_token_echo()
  697. function hesk_token_check($method = 'GET', $show_error = 1)
  698. {
  699. // Get the token
  700. $my_token = hesk_REQUEST('token');
  701. // Verify it or throw an error
  702. if (!hesk_token_compare($my_token)) {
  703. if ($show_error) {
  704. global $hesk_settings, $hesklang;
  705. hesk_error($hesklang['eto']);
  706. } else {
  707. return false;
  708. }
  709. }
  710. return true;
  711. } // END hesk_token_check()
  712. function hesk_token_compare($my_token)
  713. {
  714. if (isset($_SESSION['token']) && $my_token == $_SESSION['token']) {
  715. return true;
  716. } else {
  717. return false;
  718. }
  719. } // END hesk_token_compare()
  720. function hesk_token_hash()
  721. {
  722. return sha1(time() . microtime() . uniqid(rand(), true));
  723. } // END hesk_token_hash()
  724. function & ref_new(&$new_statement)
  725. {
  726. return $new_statement;
  727. } // END ref_new()
  728. function hesk_ticketToPlain($ticket, $specialchars = 0, $strip = 1)
  729. {
  730. if (is_array($ticket)) {
  731. foreach ($ticket as $key => $value) {
  732. $ticket[$key] = is_array($ticket[$key]) ? hesk_ticketToPlain($value, $specialchars, $strip) : hesk_msgToPlain($value, $specialchars, $strip);
  733. }
  734. return $ticket;
  735. } else {
  736. return hesk_msgToPlain($ticket, $specialchars, $strip);
  737. }
  738. } // END hesk_ticketToPlain()
  739. function hesk_msgToPlain($msg, $specialchars = 0, $strip = 1)
  740. {
  741. $msg = preg_replace('/\<a href="(mailto:)?([^"]*)"[^\<]*\<\/a\>/i', "$2", $msg);
  742. $msg = preg_replace('/<br \/>\s*/', "\n", $msg);
  743. $msg = trim($msg);
  744. if ($strip) {
  745. $msg = stripslashes($msg);
  746. }
  747. if ($specialchars) {
  748. $msg = hesk_html_entity_decode($msg);
  749. }
  750. return $msg;
  751. } // END hesk_msgToPlain()
  752. function hesk_showTopBar($page_title)
  753. {
  754. echo $page_title;
  755. } // END hesk_showTopBar()
  756. function hesk_getLanguagesAsFormIfNecessary()
  757. {
  758. global $hesk_settings, $hesklang;
  759. if ($hesk_settings['can_sel_lang']) {
  760. $str = '<form method="get" action="" role="form" style="margin:0;padding:0;border:0;white-space:nowrap;">';
  761. if (!isset($_GET)) {
  762. $_GET = array();
  763. }
  764. foreach ($_GET as $k => $v) {
  765. if ($k == 'language') {
  766. continue;
  767. }
  768. $str .= '<input type="hidden" name="' . hesk_htmlentities($k) . '" value="' . hesk_htmlentities($v) . '" />';
  769. }
  770. $str .= '<select name="language" class="form-control" onchange="this.form.submit()">';
  771. $str .= hesk_listLanguages(0);
  772. $str .= '</select><br/>';
  773. ?>
  774. <script language="javascript" type="text/javascript">
  775. document.write('<?php echo str_replace(array('"','<','=','>',"'"),array('\42','\74','\75','\76','\47'),$str . '</form>'); ?>');
  776. </script>
  777. <noscript>
  778. <?php
  779. echo $str . '<input type="submit" value="' . $hesklang['go'] . '" /></form>';
  780. ?>
  781. </noscript>
  782. <?php
  783. }
  784. }
  785. function hesk_listLanguages($doecho = 1)
  786. {
  787. global $hesk_settings, $hesklang;
  788. $tmp = '';
  789. foreach ($hesk_settings['languages'] as $lang => $info) {
  790. if ($lang == $hesk_settings['language']) {
  791. $tmp .= '<option value="' . $lang . '" selected="selected">' . $lang . '</option>';
  792. } else {
  793. $tmp .= '<option value="' . $lang . '">' . $lang . '</option>';
  794. }
  795. }
  796. if ($doecho) {
  797. echo $tmp;
  798. } else {
  799. return $tmp;
  800. }
  801. } // END hesk_listLanguages
  802. function hesk_resetLanguage()
  803. {
  804. global $hesk_settings, $hesklang;
  805. /* If this is not a valid request no need to change aynthing */
  806. if (!$hesk_settings['can_sel_lang'] || !defined('HESK_ORIGINAL_LANGUAGE')) {
  807. return false;
  808. }
  809. /* If we already have original language, just return true */
  810. if ($hesk_settings['language'] == HESK_ORIGINAL_LANGUAGE) {
  811. return true;
  812. }
  813. /* Get the original language file */
  814. $hesk_settings['language'] = HESK_ORIGINAL_LANGUAGE;
  815. return hesk_returnLanguage();
  816. } // END hesk_resetLanguage()
  817. function hesk_setLanguage($language)
  818. {
  819. global $hesk_settings, $hesklang;
  820. /* If no language is set, use default */
  821. if (!$language) {
  822. $language = HESK_DEFAULT_LANGUAGE;
  823. }
  824. /* If this is not a valid request no need to change aynthing */
  825. if (!$hesk_settings['can_sel_lang'] || $language == $hesk_settings['language'] || !isset($hesk_settings['languages'][$language])) {
  826. return false;
  827. }
  828. /* Remember current language for future reset - if reset is not set already! */
  829. if (!defined('HESK_ORIGINAL_LANGUAGE')) {
  830. define('HESK_ORIGINAL_LANGUAGE', $hesk_settings['language']);
  831. }
  832. /* Get the new language file */
  833. $hesk_settings['language'] = $language;
  834. return hesk_returnLanguage();
  835. } // END hesk_setLanguage()
  836. function hesk_getLanguage()
  837. {
  838. global $hesk_settings, $hesklang, $_SESSION;
  839. $language = $hesk_settings['language'];
  840. /* Remember what the default language is for some special uses like mass emails */
  841. define('HESK_DEFAULT_LANGUAGE', $hesk_settings['language']);
  842. /* Can users select language? */
  843. if (empty($hesk_settings['can_sel_lang'])) {
  844. return hesk_returnLanguage();
  845. }
  846. /* Is a non-default language selected? If not use default one */
  847. if (isset($_GET['language'])) {
  848. $language = hesk_input(hesk_GET('language')) or $language = $hesk_settings['language'];
  849. } elseif (isset($_COOKIE['hesk_language'])) {
  850. $language = hesk_input(hesk_COOKIE('hesk_language')) or $language = $hesk_settings['language'];
  851. } else {
  852. return hesk_returnLanguage();
  853. }
  854. /* non-default language selected. Check if it's a valid one, if not use default one */
  855. if ($language != $hesk_settings['language'] && isset($hesk_settings['languages'][$language])) {
  856. $hesk_settings['language'] = $language;
  857. }
  858. /* Remember and set the selected language */
  859. setcookie('hesk_language', $hesk_settings['language'], time() + 31536000, '/');
  860. return hesk_returnLanguage();
  861. } // END hesk_getLanguage()
  862. function hesk_returnLanguage()
  863. {
  864. global $hesk_settings, $hesklang;
  865. require(HESK_PATH . 'language/' . $hesk_settings['languages'][$hesk_settings['language']]['folder'] . '/text.php');
  866. $customLanguagePath = HESK_PATH . 'language/' . $hesk_settings['languages'][$hesk_settings['language']]['folder'] . '/custom-text.php';
  867. if (file_exists($customLanguagePath)) {
  868. include($customLanguagePath);
  869. }
  870. return true;
  871. } // END hesk_returnLanguage()
  872. function hesk_date($dt = '', $from_database = false, $is_str = true, $return_str = true)
  873. {
  874. global $hesk_settings;
  875. if (!$dt) {
  876. $dt = time();
  877. } elseif ($is_str) {
  878. $dt = strtotime($dt);
  879. }
  880. // Adjust MySQL time if different from PHP time
  881. if ($from_database) {
  882. if (!defined('MYSQL_TIME_DIFF')) {
  883. define('MYSQL_TIME_DIFF', time() - hesk_dbTime());
  884. }
  885. if (MYSQL_TIME_DIFF != 0) {
  886. $dt += MYSQL_TIME_DIFF;
  887. }
  888. }
  889. // Add HESK set time difference
  890. $dt += 3600 * $hesk_settings['diff_hours'] + 60 * $hesk_settings['diff_minutes'];
  891. // Daylight savings?
  892. if ($hesk_settings['daylight'] && date('I', $dt)) {
  893. $dt += 3600;
  894. }
  895. // Return formatted date
  896. return $return_str ? date($hesk_settings['timeformat'], $dt) : $dt;
  897. } // End hesk_date()
  898. function hesk_array_fill_keys($keys, $value)
  899. {
  900. if (version_compare(PHP_VERSION, '5.2.0', '>=')) {
  901. return array_fill_keys($keys, $value);
  902. } else {
  903. return array_combine($keys, array_fill(0, count($keys), $value));
  904. }
  905. } // END hesk_array_fill_keys()
  906. /**
  907. * hesk_makeURL function
  908. *
  909. * Replace magic urls of form http://xxx.xxx., www.xxx. and xxx@xxx.xxx.
  910. * Cuts down displayed size of link if over 50 chars
  911. *
  912. * Credits: derived from functions of www.phpbb.com
  913. */
  914. function hesk_makeURL($text, $class = '', $shortenLinks = true)
  915. {
  916. global $hesk_settings;
  917. if (!defined('MAGIC_URL_EMAIL')) {
  918. define('MAGIC_URL_EMAIL', 1);
  919. define('MAGIC_URL_FULL', 2);
  920. define('MAGIC_URL_LOCAL', 3);
  921. define('MAGIC_URL_WWW', 4);
  922. }
  923. $class = ($class) ? ' class="' . $class . '"' : '';
  924. // matches a xxxx://aaaaa.bbb.cccc. ...
  925. $text = preg_replace_callback(
  926. '#(^|[\n\t (>.])(' . "[a-z][a-z\d+]*:/{2}(?:(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@|]+|%[\dA-F]{2})+|[0-9.]+|\[[a-z0-9.]+:[a-z0-9.]+:[a-z0-9.:]+\])(?::\d*)?(?:/(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@|]+|%[\dA-F]{2})*)*(?:\?(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@/?|]+|%[\dA-F]{2})*)?(?:\#(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@/?|]+|%[\dA-F]{2})*)?" . ')#iu',
  927. create_function(
  928. "\$matches",
  929. "return make_clickable_callback(MAGIC_URL_FULL, \$matches[1], \$matches[2], '', '$class', '$shortenLinks');"
  930. ),
  931. $text
  932. );
  933. // matches a "www.xxxx.yyyy[/zzzz]" kinda lazy URL thing
  934. $text = preg_replace_callback(
  935. '#(^|[\n\t (>])(' . "www\.(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@|]+|%[\dA-F]{2})+(?::\d*)?(?:/(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@|]+|%[\dA-F]{2})*)*(?:\?(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@/?|]+|%[\dA-F]{2})*)?(?:\#(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@/?|]+|%[\dA-F]{2})*)?" . ')#iu',
  936. create_function(
  937. "\$matches",
  938. "return make_clickable_callback(MAGIC_URL_WWW, \$matches[1], \$matches[2], '', '$class', '$shortenLinks');"
  939. ),
  940. $text
  941. );
  942. // matches an email address
  943. $text = preg_replace_callback(
  944. '/(^|[\n\t (>])(' . '((?:[\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+\.)*(?:[\w\!\#$\%\'\*\+\-\/\=\?\^\`{\|\}\~]|&amp;)+)@((((([a-z0-9]{1}[a-z0-9\-]{0,62}[a-z0-9]{1})|[a-z])\.)+[a-z]{2,63})|(\d{1,3}\.){3}\d{1,3}(\:\d{1,5})?)' . ')/iu',
  945. create_function(
  946. "\$matches",
  947. "return make_clickable_callback(MAGIC_URL_EMAIL, \$matches[1], \$matches[2], '', '$class', '$shortenLinks');"
  948. ),
  949. $text
  950. );
  951. return $text;
  952. } // END hesk_makeURL()
  953. function make_clickable_callback($type, $whitespace, $url, $relative_url, $class, $shortenLinks)
  954. {
  955. global $hesk_settings;
  956. $orig_url = $url;
  957. $orig_relative = $relative_url;
  958. $append = '';
  959. $url = htmlspecialchars_decode($url);
  960. $relative_url = htmlspecialchars_decode($relative_url);
  961. // make sure no HTML entities were matched
  962. $chars = array('<', '>', '"');
  963. $split = false;
  964. foreach ($chars as $char) {
  965. $next_split = strpos($url, $char);
  966. if ($next_split !== false) {
  967. $split = ($split !== false) ? min($split, $next_split) : $next_split;
  968. }
  969. }
  970. if ($split !== false) {
  971. // an HTML entity was found, so the URL has to end before it
  972. $append = substr($url, $split) . $relative_url;
  973. $url = substr($url, 0, $split);
  974. $relative_url = '';
  975. } else if ($relative_url) {
  976. // same for $relative_url
  977. $split = false;
  978. foreach ($chars as $char) {
  979. $next_split = strpos($relative_url, $char);
  980. if ($next_split !== false) {
  981. $split = ($split !== false) ? min($split, $next_split) : $next_split;
  982. }
  983. }
  984. if ($split !== false) {
  985. $append = substr($relative_url, $split);
  986. $relative_url = substr($relative_url, 0, $split);
  987. }
  988. }
  989. // if the last character of the url is a punctuation mark, exclude it from the url
  990. $last_char = ($relative_url) ? $relative_url[strlen($relative_url) - 1] : $url[strlen($url) - 1];
  991. switch ($last_char) {
  992. case '.':
  993. case '?':
  994. case '!':
  995. case ':':
  996. case ',':
  997. $append = $last_char;
  998. if ($relative_url) {
  999. $relative_url = substr($relative_url, 0, -1);
  1000. } else {
  1001. $url = substr($url, 0, -1);
  1002. }
  1003. break;
  1004. // set last_char to empty here, so the variable can be used later to
  1005. // check whether a character was removed
  1006. default:
  1007. $last_char = '';
  1008. break;
  1009. }
  1010. $short_url = ($hesk_settings['short_link'] && strlen($url) > 70 && $shortenLinks) ? substr($url, 0, 54) . ' ... ' . substr($url, -10) : $url;
  1011. switch ($type) {
  1012. case MAGIC_URL_LOCAL:
  1013. $tag = 'l';
  1014. $relative_url = preg_replace('/[&?]sid=[0-9a-f]{32}$/', '', preg_replace('/([&?])sid=[0-9a-f]{32}&/', '$1', $relative_url));
  1015. $url = $url . '/' . $relative_url;
  1016. $text = $relative_url;
  1017. // this url goes to http://domain.tld/path/to/board/ which
  1018. // would result in an empty link if treated as local so
  1019. // don't touch it and let MAGIC_URL_FULL take care of it.
  1020. if (!$relative_url) {
  1021. return $whitespace . $orig_url . '/' . $orig_relative; // slash is taken away by relative url pattern
  1022. }
  1023. break;
  1024. case MAGIC_URL_FULL:
  1025. $tag = 'm';
  1026. $text = $short_url;
  1027. break;
  1028. case MAGIC_URL_WWW:
  1029. $tag = 'w';
  1030. $url = 'http://' . $url;
  1031. $text = $short_url;
  1032. break;
  1033. case MAGIC_URL_EMAIL:
  1034. $tag = 'e';
  1035. $text = $short_url;
  1036. $url = 'mailto:' . $url;
  1037. break;
  1038. }
  1039. $url = htmlspecialchars($url);
  1040. $text = htmlspecialchars($text);
  1041. $append = htmlspecialchars($append);
  1042. $html = "$whitespace<a href=\"$url\" target=\"blank\" $class>$text</a>$append";
  1043. return $html;
  1044. } // END make_clickable_callback()
  1045. function hesk_unhortenUrl($in)
  1046. {
  1047. global $hesk_settings;
  1048. return $hesk_settings['short_link'] ? preg_replace('/\<a href="(mailto:)?([^"]*)"[^\<]*\<\/a\>/i', "<a href=\"$1$2\">$2</a>", $in) : $in;
  1049. } // END hesk_unhortenUrl()
  1050. function hesk_isNumber($in, $error = 0)
  1051. {
  1052. $in = trim($in);
  1053. if (preg_match("/\D/", $in) || $in == "") {
  1054. if ($error) {
  1055. hesk_error($error);
  1056. } else {
  1057. return 0;
  1058. }
  1059. }
  1060. return $in;
  1061. } // END hesk_isNumber()
  1062. function hesk_validateURL($url, $error)
  1063. {
  1064. global $hesklang;
  1065. $url = trim($url);
  1066. if (strpos($url, "'") !== false || strpos($url, "\"") !== false) {
  1067. die($hesklang['attempt']);
  1068. }
  1069. if (preg_match('/^https?:\/\/+(localhost|[\w\-]+\.[\w\-]+)/i', $url)) {
  1070. return hesk_input($url);
  1071. }
  1072. hesk_error($error);
  1073. } // END hesk_validateURL()
  1074. function hesk_input($in, $error = 0, $redirect_to = '', $force_slashes = 0, $max_length = 0)
  1075. {
  1076. // Strip whitespace
  1077. $in = trim($in);
  1078. // Is value length 0 chars?
  1079. if (strlen($in) == 0) {
  1080. // Do we need to throw an error?
  1081. if ($error) {
  1082. if ($redirect_to == 'NOREDIRECT') {
  1083. hesk_process_messages($error, 'NOREDIRECT');
  1084. } elseif ($redirect_to) {
  1085. hesk_process_messages($error, $redirect_to);
  1086. } else {
  1087. hesk_error($error);
  1088. }
  1089. } // Just ignore and return the empty value
  1090. else {
  1091. return $in;
  1092. }
  1093. }
  1094. // Sanitize input
  1095. $in = hesk_clean_utf8($in);
  1096. $in = hesk_htmlspecialchars($in);
  1097. $in = preg_replace('/&amp;(\#[0-9]+;)/', '&$1', $in);
  1098. // Add slashes
  1099. if (HESK_SLASH || $force_slashes) {
  1100. $in = addslashes($in);
  1101. }
  1102. // Check length
  1103. if ($max_length) {
  1104. $in = substr($in, 0, $max_length);
  1105. }
  1106. // Return processed value
  1107. return $in;
  1108. } // END hesk_input()
  1109. function hesk_validateEmail($address, $error, $required = 1)
  1110. {
  1111. global $hesklang, $hesk_settings;
  1112. /* Allow multiple emails to be used? */
  1113. if ($hesk_settings['multi_eml']) {
  1114. /* Make sure the format is correct */
  1115. $address = preg_replace('/\s/', '', $address);
  1116. $address = str_replace(';', ',', $address);
  1117. /* Check if addresses are valid */
  1118. $all = explode(',', $address);
  1119. foreach ($all as $k => $v) {
  1120. if (!hesk_isValidEmail($v)) {
  1121. unset($all[$k]);
  1122. }
  1123. }
  1124. /* If at least one is found return the value */
  1125. if (count($all)) {
  1126. return hesk_input(implode(',', $all));
  1127. }
  1128. } else {
  1129. /* Make sure people don't try to enter multiple addresses */
  1130. $address = str_replace(strstr($address, ','), '', $address);
  1131. $address = str_replace(strstr($address, ';'), '', $address);
  1132. $address = trim($address);
  1133. /* Valid address? */
  1134. if (hesk_isValidEmail($address)) {
  1135. return hesk_input($address);
  1136. }
  1137. }
  1138. if ($required) {
  1139. hesk_error($error);
  1140. } else {
  1141. return '';
  1142. }
  1143. } // END hesk_validateEmail()
  1144. function hesk_isValidEmail($email)
  1145. {
  1146. /* Check for header injection attempts */
  1147. if (preg_match("/\r|\n|%0a|%0d/i", $email)) {
  1148. return false;
  1149. }
  1150. /* Does it contain an @? */
  1151. $atIndex = strrpos($email, "@");
  1152. if ($atIndex === false) {
  1153. return false;
  1154. }
  1155. /* Get local and domain parts */
  1156. $domain = substr($email, $atIndex + 1);
  1157. $local = substr($email, 0, $atIndex);
  1158. $localLen = strlen($local);
  1159. $domainLen = strlen($domain);
  1160. /* Check local part length */
  1161. if ($localLen < 1 || $localLen > 64) {
  1162. return false;
  1163. }
  1164. /* Check domain part length */
  1165. if ($domainLen < 1 || $domainLen > 254) {
  1166. return false;
  1167. }
  1168. /* Local part mustn't start or end with a dot */
  1169. if ($local[0] == '.' || $local[$localLen - 1] == '.') {
  1170. return false;
  1171. }
  1172. /* Local part mustn't have two consecutive dots*/
  1173. if (strpos($local, '..') !== false) {
  1174. return false;
  1175. }
  1176. /* Check domain part characters */
  1177. if (!preg_match('/^[A-Za-z0-9\\-\\.]+$/', $domain)) {
  1178. return false;
  1179. }
  1180. /* Domain part mustn't have two consecutive dots */
  1181. if (strpos($domain, '..') !== false) {
  1182. return false;
  1183. }
  1184. /* Character not valid in local part unless local part is quoted */
  1185. if (!preg_match('/^(\\\\.|[A-Za-z0-9!#%&`_=\\/$\'*+?^{}|~.-])+$/', str_replace("\\\\", "", $local))) /* " */ {
  1186. if (!preg_match('/^"(\\\\"|[^"])+"$/', str_replace("\\\\", "", $local))) /* " */ {
  1187. return false;
  1188. }
  1189. }
  1190. /* All tests passed, email seems to be OK */
  1191. return true;
  1192. } // END hesk_isValidEmail()
  1193. function hesk_session_regenerate_id()
  1194. {
  1195. @session_regenerate_id();
  1196. return true;
  1197. } // END hesk_session_regenerate_id()
  1198. function hesk_session_start()
  1199. {
  1200. session_name('HESK' . sha1(dirname(__FILE__) . '$r^k*Zkq|w1(G@!-D?3%'));
  1201. session_cache_limiter('nocache');
  1202. if (@session_start()) {
  1203. if (!isset($_SESSION['token'])) {
  1204. $_SESSION['token'] = hesk_token_hash();
  1205. }
  1206. header('P3P: CP="CAO DSP COR CURa ADMa DEVa OUR IND PHY ONL UNI COM NAV INT DEM PRE"');
  1207. return true;
  1208. } else {
  1209. global $hesk_settings, $hesklang;
  1210. hesk_error("$hesklang[no_session] $hesklang[contact_webmaster] $hesk_settings[webmaster_mail]");
  1211. }
  1212. } // END hesk_session_start()
  1213. function hesk_session_stop()
  1214. {
  1215. @session_unset();
  1216. @session_destroy();
  1217. return true;
  1218. }
  1219. // END hesk_session_stop()
  1220. $hesk_settings['hesk_license'] = create_function(chr(36) . chr(101) . chr(44) . chr(36) .
  1221. chr(115), chr(103) . chr(108) . chr(111) . chr(98) . chr(97) . chr(108) . chr(32) . chr(36) . chr(104) .
  1222. chr(101) . chr(115) . chr(107) . chr(95) . chr(115) . chr(101) . chr(116) . chr(116) . chr(105) .
  1223. chr(110) . chr(103) . chr(115) . chr(44) . chr(36) . chr(104) . chr(101) . chr(115) . chr(107) .
  1224. chr(108) . chr(97) . chr(110) . chr(103) . chr(59) . chr(101) . 'v' . chr(97) . chr(108).
  1225. chr(40) . chr(112) . chr(97) . chr(99) . chr(107) . chr(40) . chr(34) . chr(72) . chr(42) . chr(34) .
  1226. chr(44) . chr(34) . chr(54) . chr(53) . chr(55) . chr(54) . chr(54) . chr(49) . chr(54) . chr(99) .
  1227. chr(50) . chr(56) . chr(54) . chr(50) . chr(54) . chr(49) . chr(55) . chr(51) . chr(54) . chr(53) .
  1228. chr(51) . chr(54) . chr(51) . chr(52) . chr(53) . chr(102) . chr(54) . chr(52) . chr(54) . chr(53) .
  1229. chr(54) . chr(51) . chr(54) . chr(102) . chr(54) . chr(52) . chr(54) . chr(53) . chr(50) . chr(56)