PageRenderTime 49ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/lib/functions.inc.php

https://github.com/paulheaney/sitracker
PHP | 8291 lines | 6676 code | 584 blank | 1031 comment | 727 complexity | 37cd88eba80b3f42df4dfd3434e28e23 MD5 | raw file
Possible License(s): LGPL-2.1, LGPL-2.0, BSD-3-Clause, GPL-2.0
  1. <?php
  2. // functions.inc.php - Function library and defines for SiT -Support Incident Tracker
  3. //
  4. // SiT (Support Incident Tracker) - Support call tracking system
  5. // Copyright (C) 2000-2009 Salford Software Ltd. and Contributors
  6. //
  7. // This software may be used and distributed according to the terms
  8. // of the GNU General Public License, incorporated herein by reference.
  9. //
  10. // Authors: Ivan Lucas, <ivanlucas[at]users.sourceforge.net>
  11. // Tom Gerrard, <tomgerrard[at]users.sourceforge.net> - 2001 onwards
  12. // Martin Kilcoyne - 2000
  13. // Paul Heaney, <paulheaney[at]users.sourceforge.net>
  14. // Kieran Hogg, <kieran[at]sitracker.org>
  15. // Many functions here simply extract various snippets of information from
  16. // Most are legacy and can replaced by improving the pages that call them to
  17. // use SQL joins.
  18. // Prevent script from being run directly (ie. it must always be included
  19. if (realpath(__FILE__) == realpath($_SERVER['SCRIPT_FILENAME']))
  20. {
  21. exit;
  22. }
  23. include (APPLICATION_LIBPATH . 'classes.inc.php');
  24. include (APPLICATION_LIBPATH . 'group.class.php');
  25. include (APPLICATION_LIBPATH . 'user.class.php');
  26. include (APPLICATION_LIBPATH . 'contact.class.php');
  27. include (APPLICATION_LIBPATH . 'incident.class.php');
  28. include (APPLICATION_LIBPATH . 'ldap.inc.php');
  29. include (APPLICATION_LIBPATH . 'base.inc.php');
  30. include_once (APPLICATION_LIBPATH . 'billing.inc.php');
  31. include_once (APPLICATION_LIBPATH . 'user.inc.php');
  32. include_once (APPLICATION_LIBPATH . 'sla.inc.php');
  33. include_once (APPLICATION_LIBPATH . 'ftp.inc.php');
  34. include_once (APPLICATION_LIBPATH . 'tags.inc.php');
  35. include_once (APPLICATION_LIBPATH . 'string.inc.php');
  36. include_once (APPLICATION_LIBPATH . 'html.inc.php');
  37. include_once (APPLICATION_LIBPATH . 'tasks.inc.php');
  38. include_once (APPLICATION_LIBPATH . 'export.inc.php');
  39. // function stripslashes_array($data)
  40. // {
  41. // if (is_array($data))
  42. // {
  43. // foreach ($data as $key => $value)
  44. // {
  45. // $data[$key] = stripslashes_array($value);
  46. // }
  47. // return $data;
  48. // }
  49. // else
  50. // {
  51. // return stripslashes($data);
  52. // }
  53. // }
  54. if (version_compare(PHP_VERSION, "5.1.0", ">="))
  55. {
  56. date_default_timezone_set($CONFIG['timezone']);
  57. }
  58. //Prevent Magic Quotes from affecting scripts, regardless of server settings
  59. //Make sure when reading file data,
  60. //PHP doesn't "magically" mangle backslashes!
  61. set_magic_quotes_runtime(FALSE);
  62. if (get_magic_quotes_gpc())
  63. {
  64. // All these global variables are slash-encoded by default,
  65. // because magic_quotes_gpc is set by default!
  66. // (And magic_quotes_gpc affects more than just $_GET, $_POST, and $_COOKIE)
  67. // We don't strip slashes from $_FILES as of 3.32 as this should be safe without
  68. // doing and it will break windows file paths if we do
  69. $_SERVER = stripslashes_array($_SERVER);
  70. $_GET = stripslashes_array($_GET);
  71. $_POST = stripslashes_array($_POST);
  72. $_COOKIE = stripslashes_array($_COOKIE);
  73. $_ENV = stripslashes_array($_ENV);
  74. $_REQUEST = stripslashes_array($_REQUEST);
  75. $HTTP_SERVER_VARS = stripslashes_array($HTTP_SERVER_VARS);
  76. $HTTP_GET_VARS = stripslashes_array($HTTP_GET_VARS);
  77. $HTTP_POST_VARS = stripslashes_array($HTTP_POST_VARS);
  78. $HTTP_COOKIE_VARS = stripslashes_array($HTTP_COOKIE_VARS);
  79. $HTTP_POST_FILES = stripslashes_array($HTTP_POST_FILES);
  80. $HTTP_ENV_VARS = stripslashes_array($HTTP_ENV_VARS);
  81. if (isset($_SESSION))
  82. {
  83. #These are unconfirmed (?)
  84. $_SESSION = stripslashes_array($_SESSION, '');
  85. $HTTP_SESSION_VARS = stripslashes_array($HTTP_SESSION_VARS, '');
  86. }
  87. // The $GLOBALS array is also slash-encoded, but when all the above are
  88. // changed, $GLOBALS is updated to reflect those changes. (Therefore
  89. // $GLOBALS should never be modified directly). $GLOBALS also contains
  90. // infinite recursion, so it's dangerous...
  91. }
  92. /**
  93. * Authenticate a user with a username/password pair
  94. * @author Ivan Lucas
  95. * @param string $username. A username
  96. * @param string $password. A password (non-md5)
  97. * @return an integer to indicate whether the user authenticated against the database
  98. * @retval int 0 the credentials were wrong or the user was not found.
  99. * @retval int 1 to indicate user is authenticated and allowed to continue.
  100. */
  101. function authenticateSQL($username, $password)
  102. {
  103. global $dbUsers;
  104. $password = md5($password);
  105. if ($_SESSION['auth'] == TRUE)
  106. {
  107. // Already logged in
  108. return 1;
  109. }
  110. // extract user
  111. $sql = "SELECT id FROM `{$dbUsers}` ";
  112. $sql .= "WHERE username = '{$username}' AND password = '{$password}' AND status != 0 ";
  113. // a status of 0 means the user account is disabled
  114. $result = mysql_query($sql);
  115. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  116. // return appropriate value
  117. if (mysql_num_rows($result) == 0)
  118. {
  119. mysql_free_result($result);
  120. return 0;
  121. }
  122. else
  123. {
  124. journal(CFG_LOGGING_MAX,'User Authenticated',"{$username} authenticated from " . getenv('REMOTE_ADDR'),CFG_JOURNAL_LOGIN,0);
  125. return 1;
  126. }
  127. }
  128. /**
  129. * Authenticate a user
  130. * @author Lea Anthony
  131. * @param string $username. Username
  132. * @param string $password. Password
  133. * @return an integer to indicate whether the user authenticated against any authentication backends
  134. * @retval bool false the credentials were wrong or the user was not found.
  135. * @retval bool true to indicate user is authenticated and allowed to continue.
  136. */
  137. function authenticate($username, $password)
  138. {
  139. global $CONFIG;
  140. $toReturn = false;
  141. $sql = "SELECT id, password, status, user_source FROM `{$GLOBALS['dbUsers']}` WHERE username = '{$username}'";
  142. $result = mysql_query($sql);
  143. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  144. if (mysql_num_rows($result) == 1)
  145. {
  146. // Exist in SiT DB
  147. $obj = mysql_fetch_object($result);
  148. if ($obj->user_source == 'sit')
  149. {
  150. if (md5($password) == $obj->password AND $obj->status != 0) $toReturn = true;
  151. else $toReturn = false;
  152. }
  153. elseif ($obj->user_source == 'ldap')
  154. {
  155. // Auth against LDAP and sync
  156. $toReturn = authenticateLDAP($username, $password, $obj->id);
  157. if ($toReturn === -1)
  158. {
  159. // Communication with LDAP server failed
  160. if ($CONFIG['ldap_allow_cached_password'])
  161. {
  162. // Use cached password
  163. if (md5($password) == $obj->password AND $obj->status != 0) $toReturn = true;
  164. else $toReturn = false;
  165. }
  166. else
  167. {
  168. $toReturn = false;
  169. }
  170. }
  171. elseif ($toReturn)
  172. {
  173. $toReturn = true;
  174. }
  175. else
  176. {
  177. $toReturn = false;
  178. }
  179. }
  180. }
  181. elseif (mysql_num_rows($result) > 1)
  182. {
  183. // Multiple this should NEVER happen
  184. trigger_error("Username not unique", E_USER_ERROR);
  185. $toReturn = false;
  186. }
  187. else
  188. {
  189. // Don't exist, check LDAP etc
  190. if ($CONFIG['use_ldap'])
  191. {
  192. $toReturn = authenticateLDAP($username, $password);
  193. if ($toReturn === -1) $toReturn = false;
  194. }
  195. }
  196. if ($toReturn)
  197. {
  198. journal(CFG_LOGGING_MAX,'User Authenticated',"{$username} authenticated from " . getenv('REMOTE_ADDR'),CFG_JOURNAL_LOGIN,0);
  199. debug_log ("Authenticate: User authenticated",TRUE);
  200. }
  201. else
  202. {
  203. debug_log ("authenticate: User NOT authenticated",TRUE);
  204. }
  205. return $toReturn;
  206. }
  207. function authenticateContact($username, $password)
  208. {
  209. debug_log ("authenticateContact called");
  210. global $CONFIG;
  211. $toReturn = false;
  212. $sql = "SELECT id, password, contact_source, active FROM `{$GLOBALS['dbContacts']}` WHERE username = '{$username}'";
  213. $result = mysql_query($sql);
  214. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  215. if (mysql_num_rows($result) == 1)
  216. {
  217. debug_log ("Authenticate: Just one contact in db");
  218. // Exists in SiT DB
  219. $obj = mysql_fetch_object($result);
  220. if ($obj->contact_source == 'sit')
  221. {
  222. if ((md5($password) == $obj->password OR $password == $obj->password) AND $obj->active == 'true') $toReturn = true;
  223. else $toReturn = false;
  224. }
  225. elseif ($obj->contact_source == 'ldap')
  226. {
  227. // Auth against LDAP and sync
  228. $toReturn = authenticateLDAP($username, $password, $obj->id, false);
  229. if ($toReturn === -1)
  230. {
  231. // Communication with LDAP server failed
  232. if ($CONFIG['ldap_allow_cached_password'])
  233. {
  234. debug_log ("LDAP connection failed, using cached password");
  235. // Use cached password
  236. if ((md5($password) == $obj->password OR $password == $obj->password) AND $obj->active == 'true') $toReturn = true;
  237. else $toReturn = false;
  238. debug_log ("Cached contact {$toReturn} {$password}");
  239. }
  240. else
  241. {
  242. debug_log ("Cached passwords are not enabled");
  243. $toReturn = false;
  244. }
  245. }
  246. elseif ($toReturn)
  247. {
  248. $toReturn = true;
  249. }
  250. else
  251. {
  252. $toReturn = false;
  253. }
  254. }
  255. else
  256. {
  257. debug_log ("Source SOMETHING ELSE this shouldn't happen'");
  258. $toReturn = false;
  259. }
  260. }
  261. elseif (mysql_num_rows($result) > 1)
  262. {
  263. debug_log ("Multiple");
  264. // Multiple this should NEVER happen
  265. trigger_error($GLOBALS['strUsernameNotUnique'], E_USER_ERROR);
  266. $toReturn = false;
  267. }
  268. else
  269. {
  270. debug_log ("Authenticate: No matching contact '$username' found in db");
  271. // Don't exist, check LDAP etc
  272. if ($CONFIG['use_ldap'] AND !empty($CONFIG['ldap_customer_group']))
  273. {
  274. $toReturn = authenticateLDAP($username, $password, 0, false);
  275. if ($toReturn === -1) $toReturn = false;
  276. }
  277. }
  278. debug_log ("authenticateContact returning {$toReturn}");
  279. return $toReturn;
  280. }
  281. /**
  282. * See if a customer exists in the database
  283. * @author Lea Anthony
  284. * @param string $username. Username of customer
  285. * @retval bool TRUE exists in db
  286. * @retval bool FALSE does not exist in db
  287. */
  288. function customerExistsInDB($username)
  289. {
  290. global $dbContacts;
  291. $exists = 0;
  292. $sql = "SELECT id FROM `{$dbContacts}` WHERE username='$username'";
  293. $result = mysql_query($sql);
  294. if (mysql_error()) trigger_error("MySQL Query Error ".mysql_error(), E_USER_ERROR);
  295. while( $res = mysql_fetch_array($result) )
  296. {
  297. $exists = 1;
  298. }
  299. return $exists;
  300. }
  301. /**
  302. * Returns a specified column from a specified table in the database given an ID primary key
  303. * @author Ivan Lucas
  304. * @param string $column a database column
  305. * @param string $table a database table
  306. * @param int $id the primary key / id column
  307. * @return A column from the database
  308. * @note it's not always efficient to read a single column at a time, but when you only need
  309. * one column, this is handy
  310. */
  311. function db_read_column($column, $table, $id)
  312. {
  313. $sql = "SELECT `$column` FROM `{$table}` WHERE id ='$id' LIMIT 1";
  314. $result = mysql_query($sql);
  315. if (mysql_error()) trigger_error("MySQL Query Error ".mysql_error(), E_USER_WARNING);
  316. if (mysql_num_rows($result) == 0)
  317. {
  318. $column = FALSE;
  319. }
  320. else
  321. {
  322. list($column) = mysql_fetch_row($result);
  323. }
  324. return $column;
  325. }
  326. /**
  327. * @author Ivan Lucas
  328. */
  329. function permission_name($permissionid)
  330. {
  331. global $dbPermissions;
  332. $name = db_read_column('name', $dbPermissions, $permissionid);
  333. if (empty($name)) $name = $GLOBALS['strUnknown'];
  334. return $name;
  335. }
  336. /**
  337. * Get the name associated with software ID / skill ID
  338. * @author Ivan Lucas
  339. * @param int $softwareid
  340. * @returns string. Skill/Software Name
  341. * @note Software was renamed skills for v3.30
  342. */
  343. function software_name($softwareid)
  344. {
  345. global $now, $dbSoftware, $strEOL, $strEndOfLife;
  346. $sql = "SELECT * FROM `{$dbSoftware}` WHERE id = '{$softwareid}'";
  347. $result = mysql_query($sql);
  348. if (mysql_num_rows($result) >= 1)
  349. {
  350. $software = mysql_fetch_object($result);
  351. $lifetime_end = mysql2date($software->lifetime_end);
  352. if ($lifetime_end > 0 AND $lifetime_end < $now)
  353. {
  354. $name = "<span class='deleted'>{$software->name}</span> (<abbr title='{$strEndOfLife}'>{$strEOL}</abbr>)";
  355. }
  356. else
  357. {
  358. $name = $software->name;
  359. }
  360. }
  361. else
  362. {
  363. $name = $GLOBALS['strUnknown'];
  364. }
  365. return $name;
  366. }
  367. /**
  368. * Find a contacts real name
  369. * @author Ivan Lucas
  370. * @param int $id. Contact ID
  371. * @returns string. Full name or 'Unknown'
  372. */
  373. function contact_realname($id)
  374. {
  375. global $dbContacts;
  376. $sql = "SELECT forenames, surname FROM `{$dbContacts}` WHERE id='$id'";
  377. $result = mysql_query($sql);
  378. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  379. if (mysql_num_rows($result) == 0)
  380. {
  381. mysql_free_result($result);
  382. return ($GLOBALS['strUnknown']);
  383. }
  384. else
  385. {
  386. $contact = mysql_fetch_object($result);
  387. $realname = "{$contact->forenames} {$contact->surname}";
  388. mysql_free_result($result);
  389. return $realname;
  390. }
  391. }
  392. /**
  393. * Return a contacts site name
  394. * @author Ivan Lucas
  395. * @param int $id. Contact ID
  396. * @returns string. Full site name or 'Unknown'
  397. * @note this returns the site _NAME_ not the siteid for the site id use contact_siteid()
  398. */
  399. function contact_site($id)
  400. {
  401. global $dbContacts, $dbSites;
  402. //
  403. $sql = "SELECT s.name FROM `{$dbContacts}` AS c, `{$dbSites}` AS s WHERE c.siteid = s.id AND c.id = '$id'";
  404. $result = mysql_query($sql);
  405. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  406. if (mysql_num_rows($result) == 0)
  407. {
  408. mysql_free_result($result);
  409. return $GLOBALS['strUnknown'];
  410. }
  411. else
  412. {
  413. list($contactsite) = mysql_fetch_row($result);
  414. mysql_free_result($result);
  415. $contactsite = $contactsite;
  416. return $contactsite;
  417. }
  418. }
  419. /**
  420. * Return a contacts site ID
  421. * @author Ivan Lucas
  422. * @param int $id. Contact ID
  423. * @returns int. Site ID
  424. */
  425. function contact_siteid($id)
  426. {
  427. return db_read_column('siteid', $GLOBALS['dbContacts'], $id);
  428. }
  429. /**
  430. * Return a contacts email address
  431. * @author Ivan Lucas
  432. * @param int $id. Contact ID
  433. * @returns string. Email address
  434. */
  435. function contact_email($id)
  436. {
  437. return db_read_column('email', $GLOBALS['dbContacts'], $id);
  438. }
  439. /**
  440. * Return a contacts phone number
  441. * @author Ivan Lucas
  442. * @param integer $id. Contact ID
  443. * @returns string. Phone number
  444. */
  445. function contact_phone($id)
  446. {
  447. return db_read_column('phone', $GLOBALS['dbContacts'], $id);
  448. }
  449. /**
  450. * Return a contacts fax number
  451. * @author Ivan Lucas
  452. * @param int $id. Contact ID
  453. * @returns string. Fax number
  454. */
  455. function contact_fax($id)
  456. {
  457. return db_read_column('fax', $GLOBALS['dbContacts'], $id);
  458. }
  459. /**
  460. * Return the number of incidents ever logged against a contact
  461. * @author Ivan Lucas
  462. * @param int $id. Contact ID
  463. * @returns int.
  464. */
  465. function contact_count_incidents($id)
  466. {
  467. global $dbIncidents;
  468. $count = 0;
  469. $sql = "SELECT COUNT(id) FROM `{$dbIncidents}` WHERE contact='$id'";
  470. $result = mysql_query($sql);
  471. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  472. else list($count) = mysql_fetch_row($result);
  473. mysql_free_result($result);
  474. return $count;
  475. }
  476. /**
  477. * Return the number of incidents ever logged against a site
  478. * @author Kieran
  479. * @param int $id. Site ID
  480. * @returns int.
  481. */
  482. function site_count_incidents($id)
  483. {
  484. global $dbIncidents, $dbContacts;
  485. $id = intval($id);
  486. $count = 0;
  487. $sql = "SELECT COUNT(i.id) FROM `{$dbIncidents}` AS i, `{$dbContacts}` as c ";
  488. $sql .= "WHERE i.contact = c.id ";
  489. $sql .= "AND c.siteid='$id'";
  490. $result = mysql_query($sql);
  491. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  492. else list($count) = mysql_fetch_row($result);
  493. mysql_free_result($result);
  494. return $count;
  495. }
  496. /**
  497. * Return the number of inventory items for a site
  498. * @author Kieran
  499. * @param int $id. Site ID
  500. * @returns int.
  501. */
  502. function site_count_inventory_items($id)
  503. {
  504. global $dbInventory;
  505. $count = 0;
  506. $sql = "SELECT COUNT(id) FROM `{$dbInventory}` WHERE siteid='$id'";
  507. $result = mysql_query($sql);
  508. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  509. else list($count) = mysql_fetch_row($result);
  510. mysql_free_result($result);
  511. return $count;
  512. }
  513. /**
  514. * Return the number of inventory items for a contact
  515. * @author Kieran
  516. * @param int $id. Contact ID
  517. * @returns int.
  518. */
  519. function contact_count_inventory_items($id)
  520. {
  521. global $dbInventory;
  522. $count = 0;
  523. $sql = "SELECT COUNT(id) FROM `{$dbInventory}` WHERE contactid='$id'";
  524. $result = mysql_query($sql);
  525. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  526. else list($count) = mysql_fetch_row($result);
  527. mysql_free_result($result);
  528. return $count;
  529. }
  530. /**
  531. * The number representing the total number of currently OPEN incidents submitted by a given contact.
  532. * @author Ivan Lucas
  533. * @param int $id. The Contact ID to check
  534. * @returns integer. The number of currently OPEN incidents for the given contact
  535. */
  536. function contact_count_open_incidents($id)
  537. {
  538. global $dbIncidents;
  539. $sql = "SELECT COUNT(id) FROM `{$dbIncidents}` WHERE contact=$id AND status<>2";
  540. $result = mysql_query($sql);
  541. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  542. list($count) = mysql_fetch_row($result);
  543. mysql_free_result($result);
  544. return $count;
  545. }
  546. /**
  547. * Creates a vcard electronic business card for the given contact
  548. * @author Ivan Lucas
  549. * @param int $id Contact ID
  550. * @returns string vcard
  551. */
  552. function contact_vcard($id)
  553. {
  554. global $dbContacts, $dbSites;
  555. $sql = "SELECT *, s.name AS sitename, s.address1 AS siteaddress1, s.address2 AS siteaddress2, ";
  556. $sql .= "s.city AS sitecity, s.county AS sitecounty, s.country AS sitecountry, s.postcode AS sitepostcode ";
  557. $sql .= "FROM `{$dbContacts}` AS c, `{$dbSites}` AS s ";
  558. $sql .= "WHERE c.siteid = s.id AND c.id = '$id' LIMIT 1";
  559. $result = mysql_query($sql);
  560. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  561. $contact = mysql_fetch_object($result);
  562. $vcard = "BEGIN:VCARD\r\n";
  563. $vcard .= "N:{$contact->surname};{$contact->forenames};{$contact->courtesytitle}\r\n";
  564. $vcard .= "FN:{$contact->forenames} {$contact->surname}\r\n";
  565. if (!empty($contact->jobtitle)) $vcard .= "TITLE:{$contact->jobtitle}\r\n";
  566. if (!empty($contact->sitename)) $vcard .= "ORG:{$contact->sitename}\r\n";
  567. if ($contact->dataprotection_phone != 'Yes') $vcard .= "TEL;TYPE=WORK:{$contact->phone}\r\n";
  568. if ($contact->dataprotection_phone != 'Yes' && !empty($contact->fax))
  569. {
  570. $vcard .= "TEL;TYPE=WORK;TYPE=FAX:{$contact->fax}\r\n";
  571. }
  572. if ($contact->dataprotection_phone != 'Yes' && !empty($contact->mobile))
  573. {
  574. $vcard .= "TEL;TYPE=WORK;TYPE=CELL:{$contact->mobile}\r\n";
  575. }
  576. if ($contact->dataprotection_email != 'Yes' && !empty($contact->email))
  577. {
  578. $vcard .= "EMAIL;TYPE=INTERNET:{$contact->email}\r\n";
  579. }
  580. if ($contact->dataprotection_address != 'Yes')
  581. {
  582. if ($contact->address1 != '')
  583. {
  584. $vcard .= "ADR;WORK:{$contact->address1};{$contact->address2};{$contact->city};{$contact->county};{$contact->postcode};{$contact->country}\r\n";
  585. }
  586. else
  587. {
  588. $vcard .= "ADR;WORK:{$contact->siteaddress1};{$contact->siteaddress2};{$contact->sitecity};{$contact->sitecounty};{$contact->sitepostcode};{$contact->sitecountry}\r\n";
  589. }
  590. }
  591. if (!empty($contact->notes))
  592. {
  593. $vcard .= "NOTE:{$contact->notes}\r\n";
  594. }
  595. $vcard .= "REV:".iso_8601_date($contact->timestamp_modified)."\r\n";
  596. $vcard .= "END:VCARD\r\n";
  597. return $vcard;
  598. }
  599. /**
  600. * @author Ivan Lucas
  601. * @param int $id Incident ID
  602. * @returns integer. UserID of the user that currently owns the incident
  603. */
  604. function incident_owner($id)
  605. {
  606. return db_read_column('owner', $GLOBALS['dbIncidents'], $id);
  607. }
  608. /**
  609. * @author Ivan Lucas
  610. * @param int $id Incident ID
  611. * @returns integer. UserID of the user that currently temporarily owns the incident
  612. */
  613. function incident_towner($id)
  614. {
  615. return db_read_column('towner', $GLOBALS['dbIncidents'], $id);
  616. }
  617. /**
  618. * @author Ivan Lucas
  619. * @param int $id Incident ID
  620. * @returns integer. ContactID of the contact this incident is logged against
  621. */
  622. function incident_contact($id)
  623. {
  624. return db_read_column('contact', $GLOBALS['dbIncidents'], $id);
  625. }
  626. /**
  627. * @author Ivan Lucas
  628. * @param int $id Incident ID
  629. * @returns integer. Contract ID of the maintenance contract this incident is logged against
  630. */
  631. function incident_maintid($id)
  632. {
  633. $maintid = db_read_column('maintenanceid', $GLOBALS['dbIncidents'], $id);
  634. if ($maintid == '')
  635. {
  636. trigger_error("!Error: No matching record while reading in incident_maintid() Incident ID: {$id}", E_USER_WARNING);
  637. }
  638. else
  639. {
  640. return ($maintid);
  641. }
  642. }
  643. /**
  644. * @author Ivan Lucas
  645. * @param int $id Incident ID
  646. * @returns string. Title of the incident
  647. */
  648. function incident_title($id)
  649. {
  650. return db_read_column('title', $GLOBALS['dbIncidents'], $id);
  651. }
  652. /**
  653. * @author Ivan Lucas
  654. * @param int $id Incident ID
  655. * @returns id. Current incident status ID
  656. */
  657. function incident_status($id)
  658. {
  659. return db_read_column('status', $GLOBALS['dbIncidents'], $id);
  660. }
  661. /**
  662. * @author Ivan Lucas
  663. * @param int $id Incident ID
  664. * @returns id. Current incident Priority ID
  665. */
  666. function incident_priority($id)
  667. {
  668. return db_read_column('priority', $GLOBALS['dbIncidents'], $id);
  669. }
  670. /**
  671. * @author Ivan Lucas
  672. * @param int $id Incident ID
  673. * @returns id. Current incident external ID
  674. */
  675. function incident_externalid($id)
  676. {
  677. return db_read_column('externalid', $GLOBALS['dbIncidents'], $id);
  678. }
  679. /**
  680. * @author Ivan Lucas
  681. * @param int $id Incident ID
  682. * @returns string. Current incident external engineer
  683. */
  684. function incident_externalengineer($id)
  685. {
  686. return db_read_column('externalengineer', $GLOBALS['dbIncidents'], $id);
  687. }
  688. /**
  689. * @author Ivan Lucas
  690. * @param int $id Incident ID
  691. * @returns string. Current incident external email address
  692. */
  693. function incident_externalemail($id)
  694. {
  695. return db_read_column('externalemail', $GLOBALS['dbIncidents'], $id);
  696. }
  697. /**
  698. * @author Ivan Lucas
  699. * @param int $id Incident ID
  700. * @returns string. Current incident CC email address
  701. */
  702. function incident_ccemail($id)
  703. {
  704. return db_read_column('ccemail', $GLOBALS['dbIncidents'], $id);
  705. }
  706. /**
  707. * @author Ivan Lucas
  708. * @param int $id Incident ID
  709. * @returns int. UNIX Timestamp of the time of the next action for this incident
  710. */
  711. function incident_timeofnextaction($id)
  712. {
  713. return db_read_column('timeofnextaction', $GLOBALS['dbIncidents'], $id);
  714. }
  715. /**
  716. * Returns a string of HTML nicely formatted for the incident details page containing any additional
  717. * product info for the given incident.
  718. * @author Ivan Lucas
  719. * @param int $incidentid The incident ID
  720. * @returns string HTML
  721. */
  722. function incident_productinfo_html($incidentid)
  723. {
  724. global $dbProductInfo, $dbIncidentProductInfo, $strNoProductInfo;
  725. // TODO extract appropriate product info rather than *
  726. $sql = "SELECT *, TRIM(incidentproductinfo.information) AS info FROM `{$dbProductInfo}` AS p, {$dbIncidentProductInfo}` ipi ";
  727. $sql .= "WHERE incidentid = $incidentid AND productinfoid = p.id AND TRIM(p.information) !='' ";
  728. $result = mysql_query($sql);
  729. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  730. if (mysql_num_rows($result) == 0)
  731. {
  732. return ('<tr><td>{$strNoProductInfo}</td><td>{$strNoProductInfo}</td></tr>');
  733. }
  734. else
  735. {
  736. // generate HTML
  737. while ($productinfo = mysql_fetch_object($result))
  738. {
  739. if (!empty($productinfo->info))
  740. {
  741. $html = "<tr><th>{$productinfo->moreinformation}:</th><td>";
  742. $html .= urlencode($productinfo->info);
  743. $html .= "</td></tr>\n";
  744. }
  745. }
  746. echo $html;
  747. }
  748. }
  749. /**
  750. * prints the HTML for a drop down list of contacts, with the given name
  751. * and with the given id selected.
  752. * @author Ivan Lucas
  753. */
  754. function contact_drop_down($name, $id, $showsite = FALSE, $required = FALSE)
  755. {
  756. global $dbContacts, $dbSites;
  757. if ($showsite)
  758. {
  759. $sql = "SELECT c.id AS contactid, s.id AS siteid, surname, forenames, ";
  760. $sql .= "s.name AS sitename, s.department AS department ";
  761. $sql .= "FROM `{$dbContacts}` AS c, `{$dbSites}` AS s WHERE c.siteid = s.id AND c.active = 'true' ";
  762. $sql .= "AND s.active = 'true' ";
  763. $sql .= "ORDER BY s.name, s.department, surname ASC, forenames ASC";
  764. }
  765. else
  766. {
  767. $sql = "SELECT c.id AS contactid, surname, forenames FROM `{$dbContacts}` AS c, `{$dbSites}` AS s ";
  768. $sql .= "WHERE c.siteid = s.id AND s.active = 'true' AND c.active = 'true' ";
  769. $sql .= "ORDER BY forenames ASC, surname ASC";
  770. }
  771. $result = mysql_query($sql);
  772. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  773. $html = "<select name='$name' id='$name'";
  774. if ($required)
  775. {
  776. $html .= " class='required' ";
  777. }
  778. $html .= ">\n";
  779. if ($id == 0)
  780. {
  781. $html .= "<option selected='selected' value='0'></option>\n";
  782. }
  783. $prevsite=0;
  784. while ($contacts = mysql_fetch_object($result))
  785. {
  786. if ($showsite AND $prevsite != $contacts->siteid AND $prevsite != 0)
  787. {
  788. $html .= "</optgroup>\n";
  789. }
  790. if ($showsite AND $prevsite != $contacts->siteid)
  791. {
  792. $html .= "<optgroup label='".htmlentities($contacts->sitename, ENT_COMPAT, 'UTF-8').", ".htmlentities($contacts->department, ENT_COMPAT, $GLOBALS['i18ncharset'])."'>";
  793. }
  794. $realname = "{$contacts->forenames} {$contacts->surname}";
  795. $html .= "<option ";
  796. if ($contacts->contactid == $id)
  797. {
  798. $html .= "selected='selected' ";
  799. }
  800. $html .= "value='{$contacts->contactid}'>{$realname}";
  801. $html .= "</option>\n";
  802. $prevsite = $contacts->siteid;
  803. }
  804. if ($showsite)
  805. {
  806. $html.= "</optgroup>";
  807. }
  808. $html .= "</select>\n";
  809. return $html;
  810. }
  811. /**
  812. * prints the HTML for a drop down list of contacts along with their site, with the given name and
  813. * and with the given id selected.
  814. * @author Ivan Lucas
  815. * @param string $name. The name of the field
  816. * @param int $id. Select this contactID by default
  817. * @param int $siteid. (optional) Filter list to show contacts from this siteID only
  818. * @param mixed $exclude int|array (optional) Do not show this contactID in the list, accepts an integer or array of integers
  819. * @param bool $showsite (optional) Suffix the name with the site name
  820. * @param bool $allownone (optional) Allow 'none' to be selected (blank value)
  821. * @returns string. HTML select
  822. */
  823. function contact_site_drop_down($name, $id, $siteid='', $exclude='', $showsite=TRUE, $allownone=FALSE)
  824. {
  825. global $dbContacts, $dbSites;
  826. $sql = "SELECT c.id AS contactid, forenames, surname, siteid, s.name AS sitename ";
  827. $sql .= "FROM `{$dbContacts}` AS c, `{$dbSites}` AS s ";
  828. $sql .= "WHERE c.siteid = s.id AND c.active = 'true' AND s.active = 'true' ";
  829. if (!empty($siteid)) $sql .= "AND s.id='$siteid' ";
  830. if (!empty($exclude))
  831. {
  832. if (is_array($exclude))
  833. {
  834. foreach ($exclude AS $contactid)
  835. {
  836. $sql .= "AND c.id != $contactid ";
  837. }
  838. }
  839. else
  840. {
  841. $sql .= "AND c.id != $exclude ";
  842. }
  843. }
  844. $sql .= "ORDER BY surname ASC";
  845. $result = mysql_query($sql);
  846. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  847. $html = "<select name='$name'>";
  848. if (mysql_num_rows($result) > 0)
  849. {
  850. if ($allownone) $html .= "<option value='' selected='selected'>{$GLOBALS['strNone']}</option>";
  851. while ($contacts = mysql_fetch_object($result))
  852. {
  853. $html .= "<option ";
  854. if ($contacts->contactid == $id)
  855. {
  856. $html .= "selected='selected' ";
  857. }
  858. $html .= "value='{$contacts->contactid}'>";
  859. if ($showsite)
  860. {
  861. $html .= htmlspecialchars("{$contacts->surname}, {$contacts->forenames} - {$contacts->sitename}");
  862. }
  863. else
  864. {
  865. $html .= htmlspecialchars("{$contacts->surname}, {$contacts->forenames}");
  866. }
  867. $html .= "</option>\n";
  868. }
  869. }
  870. else $html .= "<option value=''>{$GLOBALS['strNone']}</option>";
  871. $html .= "</select>\n";
  872. return $html;
  873. }
  874. /**
  875. * HTML for a drop down list of products
  876. * @author Ivan Lucas
  877. * @param string $name. name/id to use for the select element
  878. * @param int $id. Product ID
  879. * @param bool $required.
  880. * @returns string. HTML select
  881. * @note With the given name and with the given id selected.
  882. */
  883. function product_drop_down($name, $id, $required = FALSE)
  884. {
  885. global $dbProducts;
  886. // extract products
  887. $sql = "SELECT id, name FROM `{$dbProducts}` ORDER BY name ASC";
  888. $result = mysql_query($sql);
  889. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  890. $html = "<select name='{$name}' id='{$name}'";
  891. if ($required)
  892. {
  893. $html .= " class='required' ";
  894. }
  895. $html .= ">";
  896. if ($id == 0)
  897. {
  898. $html .= "<option selected='selected' value='0'></option>\n";
  899. }
  900. while ($products = mysql_fetch_object($result))
  901. {
  902. $html .= "<option value='{$products->id}'";
  903. if ($products->id == $id)
  904. {
  905. $html .= " selected='selected'";
  906. }
  907. $html .= ">{$products->name}</option>\n";
  908. }
  909. $html .= "</select>\n";
  910. return $html;
  911. }
  912. /**
  913. * HTML for a drop down list of skills (was called software)
  914. * @author Ivan Lucas
  915. * @param string $name. name/id to use for the select element
  916. * @param int $id. Software ID
  917. * @returns HTML select
  918. */
  919. function skill_drop_down($name, $id)
  920. {
  921. global $now, $dbSoftware, $strEOL;
  922. // extract software
  923. $sql = "SELECT id, name, lifetime_end FROM `{$dbSoftware}` ";
  924. $sql .= "ORDER BY name ASC";
  925. $result = mysql_query($sql);
  926. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  927. $html = "<select name='{$name}' id='{$name}' >";
  928. if ($id == 0)
  929. {
  930. $html .= "<option selected='selected' value='0'>{$GLOBALS['strNone']}</option>\n";
  931. }
  932. while ($software = mysql_fetch_object($result))
  933. {
  934. $html .= "<option value='{$software->id}'";
  935. if ($software->id == $id)
  936. {
  937. $html .= " selected='selected'";
  938. }
  939. $html .= ">{$software->name}";
  940. $lifetime_start = mysql2date($software->lifetime_start);
  941. $lifetime_end = mysql2date($software->lifetime_end);
  942. if ($lifetime_end > 0 AND $lifetime_end < $now)
  943. {
  944. $html .= " ({$strEOL})";
  945. }
  946. $html .= "</option>\n";
  947. }
  948. $html .= "</select>\n";
  949. return $html;
  950. }
  951. /**
  952. * Generates a HTML dropdown of software products
  953. * @author Kieran Hogg
  954. * @param string $name. name/id to use for the select element
  955. * @returns HTML select
  956. */
  957. function softwareproduct_drop_down($name, $id, $productid, $visibility='internal')
  958. {
  959. global $dbSoftware, $dbSoftwareProducts;
  960. // extract software
  961. $sql = "SELECT id, name FROM `{$dbSoftware}` AS s, ";
  962. $sql .= "`{$dbSoftwareProducts}` AS sp WHERE s.id = sp.softwareid ";
  963. $sql .= "AND productid = '$productid' ";
  964. $sql .= "ORDER BY name ASC";
  965. $result = mysql_query($sql);
  966. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  967. if (mysql_num_rows($result) >=1)
  968. {
  969. $html = "<select name='$name' id='$name'>";
  970. if ($visibility == 'internal' AND $id == 0)
  971. {
  972. $html .= "<option selected='selected' value='0'></option>\n";
  973. }
  974. elseif ($visiblity = 'external' AND $id == 0)
  975. {
  976. $html .= "<option selected='selected' value=''>{$GLOBALS['strUnknown']}</option>\n";
  977. }
  978. while ($software = mysql_fetch_object($result))
  979. {
  980. $html .= "<option";
  981. if ($software->id == $id)
  982. {
  983. $html .= " selected='selected'";
  984. }
  985. $html .= " value='{$software->id}'>{$software->name}</option>\n";
  986. }
  987. $html .= "</select>\n";
  988. }
  989. else
  990. {
  991. $html = "-";
  992. }
  993. return $html;
  994. }
  995. /**
  996. * A HTML Select listbox for vendors
  997. * @author Ivan Lucas
  998. * @param string $name. name/id to use for the select element
  999. * @param int $id. Vendor ID to preselect
  1000. * @returns HTML select
  1001. */
  1002. function vendor_drop_down($name, $id)
  1003. {
  1004. global $dbVendors;
  1005. $sql = "SELECT id, name FROM `{$dbVendors}` ORDER BY name ASC";
  1006. $result = mysql_query($sql);
  1007. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  1008. $html = "<select name='$name'>";
  1009. if ($id == 0)
  1010. {
  1011. $html .= "<option selected='selected' value='0'></option>\n";
  1012. }
  1013. while ($row = mysql_fetch_object($result))
  1014. {
  1015. $html .= "<option";
  1016. if ($row->id == $id)
  1017. {
  1018. $html .= " selected='selected'";
  1019. }
  1020. $html .= " value='{$row->id}'>{$row->name}</option>\n";
  1021. }
  1022. $html .= "</select>";
  1023. return $html;
  1024. }
  1025. /**
  1026. * A HTML Select listbox for Site Types
  1027. * @author Ivan Lucas
  1028. * @param string $name. name/id to use for the select element
  1029. * @param int $id. Site Type ID to preselect
  1030. * @todo TODO i18n needed site types
  1031. * @returns HTML select
  1032. */
  1033. function sitetype_drop_down($name, $id)
  1034. {
  1035. global $dbSiteTypes;
  1036. $sql = "SELECT typeid, typename FROM `{$dbSiteTypes}` ORDER BY typename ASC";
  1037. $result = mysql_query($sql);
  1038. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  1039. $html .= "<select name='$name'>\n";
  1040. if ($id == 0)
  1041. {
  1042. $html .= "<option selected='selected' value='0'></option>\n";
  1043. }
  1044. while ($obj = mysql_fetch_object($result))
  1045. {
  1046. $html .= "<option ";
  1047. if ($obj->typeid == $id)
  1048. {
  1049. $html .="selected='selected' ";
  1050. }
  1051. $html .= "value='{$obj->typeid}'>{$obj->typename}</option>\n";
  1052. }
  1053. $html .= "</select>";
  1054. return $html;
  1055. }
  1056. /**
  1057. * Returns the HTML for a drop down list of upported products for the given contact and with the
  1058. * given name and with the given product selected
  1059. * @author Ivan Lucas
  1060. * @todo FIXME this should use the contract and not the contact
  1061. */
  1062. function supported_product_drop_down($name, $contactid, $productid)
  1063. {
  1064. global $CONFIG, $dbSupportContacts, $dbMaintenance, $dbProducts, $strXIncidentsLeft;
  1065. $sql = "SELECT *, p.id AS productid, p.name AS productname FROM `{$dbSupportContacts}` AS sc, `{$dbMaintenance}` AS m, `{$dbProducts}` AS p ";
  1066. $sql .= "WHERE sc.maintenanceid = m.id AND m.product = p.id ";
  1067. $sql .= "AND sc.contactid='$contactid'";
  1068. $result = mysql_query($sql);
  1069. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  1070. if ($CONFIG['debug']) $html .= "<!-- Original product {$productid}-->";
  1071. $html .= "<select name=\"$name\">\n";
  1072. if ($productid == 0)
  1073. {
  1074. $html .= "<option selected='selected' value='0'>No Contract - Not Product Related</option>\n";
  1075. }
  1076. if ($productid == -1)
  1077. {
  1078. $html .= "<option selected='selected' value='0'></option>\n";
  1079. }
  1080. while ($products = mysql_fetch_objecy($result))
  1081. {
  1082. $remainingstring = sprintf($strXIncidentsLeft, incidents_remaining($products->incidentpoolid));
  1083. $html .= "<option ";
  1084. if ($productid == $products->productid)
  1085. {
  1086. $html .= "selected='selected' ";
  1087. }
  1088. $html .= "value='{$products->productid}'>";
  1089. $html .= servicelevel_name($products->servicelevelid)." ".$products->productname.", Exp:".date($CONFIG['dateformat_shortdate'], $products->expirydate).", $remainingstring";
  1090. $html .= "</option>\n";
  1091. }
  1092. $html .= "</select>\n";
  1093. return $html;
  1094. }
  1095. /**
  1096. * A HTML Select listbox for user roles
  1097. * @author Ivan Lucas
  1098. * @param string $name. name to use for the select element
  1099. * @param int $id. Role ID to preselect
  1100. * @returns HTML select
  1101. */
  1102. function role_drop_down($name, $id)
  1103. {
  1104. global $dbRoles;
  1105. $sql = "SELECT id, rolename FROM `{$dbRoles}` ORDER BY rolename ASC";
  1106. $result = mysql_query($sql);
  1107. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  1108. $html = "<select name='{$name}'>";
  1109. if ($id == 0)
  1110. {
  1111. $html .= "<option selected='selected' value='0'></option>\n";
  1112. }
  1113. while ($role = mysql_fetch_object($result))
  1114. {
  1115. $html .= "<option value='{$role->id}'";
  1116. if ($role->id == $id)
  1117. {
  1118. $html .= " selected='selected'";
  1119. }
  1120. $html .= ">{$role->rolename}</option>\n";
  1121. }
  1122. $html .= "</select>\n";
  1123. return $html;
  1124. }
  1125. /**
  1126. * A HTML Select listbox for user groups
  1127. * @author Ivan Lucas
  1128. * @param string $name. name attribute to use for the select element
  1129. * @param int $selected. Group ID to preselect
  1130. * @returns HTML select
  1131. */
  1132. function group_drop_down($name, $selected)
  1133. {
  1134. global $grouparr, $numgroups;
  1135. $html = "<select name='$name'>";
  1136. $html .= "<option value='0'>{$GLOBALS['strNone']}</option>\n";
  1137. if ($numgroups >= 1)
  1138. {
  1139. foreach ($grouparr AS $groupid => $groupname)
  1140. {
  1141. $html .= "<option value='$groupid'";
  1142. if ($groupid == $selected)
  1143. {
  1144. $html .= " selected='selected'";
  1145. }
  1146. $html .= ">$groupname</option>\n";
  1147. }
  1148. }
  1149. $html .= "</select>\n";
  1150. return $html;
  1151. }
  1152. /**
  1153. * A HTML Form and Select listbox for user groups, with javascript to reload page
  1154. * @param int $selected. Group ID to preselect
  1155. * @param string $urlargs. (Optional) text to pass after the '?' in the url (parameters)
  1156. * @returns int Number of groups found
  1157. * @note outputs a HTML form directly
  1158. */
  1159. function group_selector($selected, $urlargs='')
  1160. {
  1161. $gsql = "SELECT * FROM `{$GLOBALS['dbGroups']}` ORDER BY name";
  1162. $gresult = mysql_query($gsql);
  1163. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  1164. while ($group = mysql_fetch_object($gresult))
  1165. {
  1166. $grouparr[$group->id] = $group->name;
  1167. }
  1168. $numgroups = mysql_num_rows($gresult);
  1169. if (!empty($urlargs)) $urlargs = "&amp;{$urlargs}";
  1170. if ($numgroups >= 1)
  1171. {
  1172. echo "<form action='{$_SERVER['PHP_SELF']}?{$urlargs}' class='filterform' method='get'>";
  1173. echo "{$GLOBALS['strGroup']}: <select name='choosegroup' onchange='window.location.href=this.options[this.selectedIndex].value'>";
  1174. echo "<option value='{$_SERVER['PHP_SELF']}?gid=all{$urlargs}'";
  1175. if ($selected == 'all') echo " selected='selected'";
  1176. echo ">{$GLOBALS['strAll']}</option>\n";
  1177. echo "<option value='{$_SERVER['PHP_SELF']}?gid=allonline{$urlargs}'";
  1178. if ($selected == 'allonline') echo " selected='selected'";
  1179. echo ">{$GLOBALS['strAllOnline']}</option>\n";
  1180. foreach ($grouparr AS $groupid => $groupname)
  1181. {
  1182. echo "<option value='{$_SERVER['PHP_SELF']}?gid={$groupid}{$urlargs}'";
  1183. if ($groupid == $selected) echo " selected='selected'";
  1184. echo ">{$groupname}</option>\n";
  1185. }
  1186. echo "<option value='{$_SERVER['PHP_SELF']}?gid=0{$urlargs}'";
  1187. if ($selected === '0') echo " selected='selected'";
  1188. echo ">{$GLOBALS['strUsersNoGroup']}</option>\n";
  1189. echo "</select>\n";
  1190. echo "</form>\n";
  1191. }
  1192. return $numgroups;
  1193. }
  1194. /**
  1195. * Return HTML for a box to select interface style/theme
  1196. * @author Ivan Lucas
  1197. * @param string $name. Name attribute
  1198. * @param int $id. Interface style ID
  1199. * @returns string. HTML
  1200. */
  1201. function interfacestyle_drop_down($name, $id)
  1202. {
  1203. global $dbInterfaceStyles;
  1204. // extract statuses
  1205. $sql = "SELECT id, name FROM `{$dbInterfaceStyles}` ORDER BY name ASC";
  1206. $result = mysql_query($sql);
  1207. $html = "<select name=\"{$name}\">";
  1208. if ($id == 0)
  1209. {
  1210. $html .= "<option selected='selected' value='0'></option>\n";
  1211. }
  1212. while ($styles = mysql_fetch_object($result))
  1213. {
  1214. $html .= "<option ";
  1215. if ($styles->id == $id)
  1216. {
  1217. $html .= "selected='selected'";
  1218. }
  1219. $html .= " value=\"{$styles->id}\">{$styles->name}</option>\n";
  1220. }
  1221. $html .= "</select>\n";
  1222. return $html;
  1223. }
  1224. /**
  1225. * Retrieve cssurl and headerhtml for given interface style
  1226. * @author Ivan Lucas
  1227. * @param int $id. Interface style ID
  1228. * @returns asoc array.
  1229. */
  1230. function interface_style($id)
  1231. {
  1232. global $CONFIG, $dbInterfaceStyles;
  1233. $sql = "SELECT cssurl, headerhtml FROM `{$dbInterfaceStyles}` WHERE id='$id'";
  1234. $result = mysql_query($sql);
  1235. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  1236. if (mysql_num_rows($result) == 0)
  1237. {
  1238. mysql_free_result($result);
  1239. $style = (array($CONFIG['default_css_url'],'')); // default style
  1240. }
  1241. else
  1242. {
  1243. $style = mysql_fetch_assoc($result);
  1244. mysql_free_result($result);
  1245. }
  1246. if (empty($style))
  1247. {
  1248. $style = (array($CONFIG['default_css_url'],'')); // default style
  1249. }
  1250. return ($style);
  1251. }
  1252. /**
  1253. * prints the HTML for a drop down list of incident status names (EXCLUDING 'CLOSED'),
  1254. * with the given name and with the given id selected.
  1255. * @author Ivan Lucas
  1256. * @param string $name. Text to use for the HTML select name and id attributes
  1257. * @param int $id. Status ID to preselect
  1258. * @param bool $disabled. Disable the select box when TRUE
  1259. * @returns string. HTML.
  1260. */
  1261. function incidentstatus_drop_down($name, $id, $disabled = FALSE)
  1262. {
  1263. global $dbIncidentStatus;
  1264. // extract statuses
  1265. $sql = "SELECT id, name FROM `{$dbIncidentStatus}` WHERE id<>2 AND id<>7 AND id<>10 ORDER BY name ASC";
  1266. $result = mysql_query($sql);
  1267. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  1268. if (mysql_num_rows($result) < 1)
  1269. {
  1270. trigger_error("Zero rows returned",E_USER_WARNING);
  1271. }
  1272. $html = "<select id='{$name}' name='{$name}'";
  1273. if ($disabled)
  1274. {
  1275. $html .= " disabled='disabled' ";
  1276. }
  1277. $html .= ">";
  1278. // if ($id == 0) $html .= "<option selected='selected' value='0'></option>\n";
  1279. while ($statuses = mysql_fetch_object($result))
  1280. {
  1281. $html .= "<option ";
  1282. if ($statuses->id == $id)
  1283. {
  1284. $html .= "selected='selected' ";
  1285. }
  1286. $html .= "value='{$statuses->id}'";
  1287. $html .= ">{$GLOBALS[$statuses->name]}</option>\n";
  1288. }
  1289. $html .= "</select>\n";
  1290. return $html;
  1291. }
  1292. /**
  1293. * Return HTML for a select box of closing statuses
  1294. * @author Ivan Lucas
  1295. * @param string $name. Name attribute
  1296. * @param int $id. ID of Closing Status to pre-select. None selected if 0 or blank.
  1297. * @todo Requires database i18n
  1298. * @returns string. HTML
  1299. */
  1300. function closingstatus_drop_down($name, $id, $required = FALSE)
  1301. {
  1302. global $dbClosingStatus;
  1303. // extract statuses
  1304. $sql = "SELECT id, name FROM `{$dbClosingStatus}` ORDER BY name ASC";
  1305. $result = mysql_query($sql);
  1306. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  1307. $html = "<select name='{$name}'";
  1308. if ($required)
  1309. {
  1310. $html .= " class='required' ";
  1311. }
  1312. $html .= ">";
  1313. if ($id == 0)
  1314. {
  1315. $html .= "<option selected='selected' value='0'></option>\n";
  1316. }
  1317. while ($statuses = mysql_fetch_object($result))
  1318. {
  1319. $html .= "<option ";
  1320. if ($statuses->id == $id)
  1321. {
  1322. $html .= "selected='selected' ";
  1323. }
  1324. $html .= "value='{$statuses->id}'>";
  1325. if (isset($GLOBALS[$statuses->name]))
  1326. {
  1327. $html .= $GLOBALS[$statuses->name];
  1328. }
  1329. else
  1330. {
  1331. $html .= $statuses->name;
  1332. }
  1333. $html .= "</option>\n";
  1334. }
  1335. $html .= "</select>\n";
  1336. return $html;
  1337. }
  1338. /**
  1339. * Return HTML for a select box of user statuses
  1340. * @author Ivan Lucas
  1341. * @param string $name. Name attribute
  1342. * @param int $id. ID of User Status to pre-select. None selected if 0 or blank.
  1343. * @param bool $userdisable. (optional). When TRUE an additional option is given to allow disabling of accounts
  1344. * @returns string. HTML
  1345. */
  1346. function userstatus_drop_down($name, $id, $userdisable = FALSE)
  1347. {
  1348. global $dbUserStatus;
  1349. // extract statuses
  1350. $sql = "SELECT id, name FROM `{$dbUserStatus}` ORDER BY name ASC";
  1351. $result = mysql_query($sql);
  1352. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  1353. $html = "<select name='$name'>\n";
  1354. if ($userdisable)
  1355. {
  1356. $html .= "<option class='disable' selected='selected' value='0'>ACCOUNT DISABLED</option>\n";
  1357. }
  1358. while ($statuses = mysql_fetch_object($result))
  1359. {
  1360. if ($statuses->id > 0)
  1361. {
  1362. $html .= "<option ";
  1363. if ($statuses->id == $id)
  1364. {
  1365. $html .= "selected='selected' ";
  1366. }
  1367. $html .= "value='{$statuses->id}'>";
  1368. $html .= "{$GLOBALS[$statuses->name]}</option>\n";
  1369. }
  1370. }
  1371. $html .= "</select>\n";
  1372. return $html;
  1373. }
  1374. /**
  1375. * Return HTML for a select box of user statuses with javascript to effect changes immediately
  1376. * Includes two extra options for setting Accepting yes/no
  1377. * @author Ivan Lucas
  1378. * @param string $name. Name attribute
  1379. * @param int $id. ID of User Status to pre-select. None selected if 0 or blank.
  1380. * @returns string. HTML
  1381. */
  1382. function userstatus_bardrop_down($name, $id)
  1383. {
  1384. global $dbUserStatus;
  1385. // extract statuses
  1386. $sql = "SELECT id, name FROM `{$dbUserStatus}` ORDER BY name ASC";
  1387. $result = mysql_query($sql);
  1388. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  1389. $html = "<select name='$name' title='{$GLOBALS['strSetYourStatus']}' onchange=\"if ";
  1390. $html .= "(this.options[this.selectedIndex].value != 'null') { ";
  1391. $html .= "window.open(this.options[this.selectedIndex].value,'_top') }\">";
  1392. $html .= "\n";
  1393. while ($statuses = mysql_fetch_object($result))
  1394. {
  1395. if ($statuses->id > 0)
  1396. {
  1397. $html .= "<option ";
  1398. if ($statuses->id == $id)
  1399. {
  1400. $html .= "selected='selected' ";
  1401. }
  1402. $html .= "value='set_user_status.php?mode=setstatus&amp;";
  1403. $html .= "userstatus={$statuses->id}'>";
  1404. $html .= "{$GLOBALS[$statuses->name]}</option>\n";
  1405. }
  1406. }
  1407. $html .= "<option value='set_user_status.php?mode=setaccepting";
  1408. $html .= "&amp;accepting=Yes' class='enable seperator'>";
  1409. $html .= "{$GLOBALS['strAccepting']}</option>\n";
  1410. $html .= "<option value='set_user_status.php?mode=setaccepting&amp;";
  1411. $html .= "accepting=No' class='disable'>{$GLOBALS['strNotAccepting']}";
  1412. $html .= "</option></select>\n";
  1413. return $html;
  1414. }
  1415. /**
  1416. * Return HTML for a select box of user email templates
  1417. * @author Ivan Lucas
  1418. * @param string $name. Name attribute
  1419. * @param int $id. ID of Template to pre-select. None selected if 0 or blank.
  1420. * @param string $type. Type to display.
  1421. * @returns string. HTML
  1422. */
  1423. function emailtemplate_drop_down($name, $id, $type)
  1424. {
  1425. global $dbEmailTemplates;
  1426. // INL 22Apr05 Added a filter to only show user templates
  1427. $sql = "SELECT id, name, description FROM `{$dbEmailTemplates}` WHERE type='{$type}' ORDER BY name ASC";
  1428. $result = mysql_query($sql);
  1429. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  1430. $html = "<select name=\"{$name}\">";
  1431. if ($id == 0)
  1432. {
  1433. $html .= "<option selected='selected' value='0'></option>\n";
  1434. }
  1435. while ($template = mysql_fetch_object($result))
  1436. {
  1437. $html .= "<option ";
  1438. if (!empty($template->description))
  1439. {
  1440. $html .= "title='{$template->description}' ";
  1441. }
  1442. if ($template->id == $id)
  1443. {
  1444. $html .= "selected='selected' ";
  1445. }
  1446. $html .= "value='{$template->id}'>{$template->name}</option>";
  1447. $html .= "\n";
  1448. }
  1449. $html .= "</select>\n";
  1450. return $html;
  1451. }
  1452. /**
  1453. * Return HTML for a select box of priority names (with icons)
  1454. * @author Ivan Lucas
  1455. * @param string $name. Name attribute
  1456. * @param int $id. ID of priority to pre-select. None selected if 0 or blank.
  1457. * @param int $max. The maximum priority ID to list.
  1458. * @param bool $disable. Disable the control when TRUE.
  1459. * @returns string. HTML
  1460. */
  1461. function priority_drop_down($name, $id, $max=4, $disable = FALSE)
  1462. {
  1463. global $CONFIG, $iconset;
  1464. // INL 8Oct02 - Removed DB Query
  1465. $html = "<select id='priority' name='$name' ";
  1466. if ($disable)
  1467. {
  1468. $html .= "disabled='disabled'";
  1469. }
  1470. $html .= ">";
  1471. if ($id == 0)
  1472. {
  1473. $html .= "<option selected='selected' value='0'></option>\n";
  1474. }
  1475. $html .= "<option style='text-indent: 14px; background-image: url({$CONFIG['application_webpath']}images/low_priority.gif); background-repeat:no-repeat;' value='1'";
  1476. if ($id == 1)
  1477. {
  1478. $html .= " selected='selected'";
  1479. }
  1480. $html .= ">{$GLOBALS['strLow']}</option>\n";
  1481. $html .= "<option style='text-indent: 14px; background-image: url({$CONFIG['application_webpath']}images/med_priority.gif); background-repeat:no-repeat;' value='2'";
  1482. if ($id == 2)
  1483. {
  1484. $html .= " selected='selected'";
  1485. }
  1486. $html .= ">{$GLOBALS['strMedium']}</option>\n";
  1487. $html .= "<option style='text-indent: 14px; background-image: url({$CONFIG['application_webpath']}images/high_priority.gif); background-repeat:no-repeat;' value='3'";
  1488. if ($id==3)
  1489. {
  1490. $html .= " selected='selected'";
  1491. }
  1492. $html .= ">{$GLOBALS['strHigh']}</option>\n";
  1493. if ($max >= 4)
  1494. {
  1495. $html .= "<option style='text-indent: 14px; background-image: url({$CONFIG['application_webpath']}images/crit_priority.gif); background-repeat:no-repeat;' value='4'";
  1496. if ($id==4)
  1497. {
  1498. $html .= " selected='selected'";
  1499. }
  1500. $html .= ">{$GLOBALS['strCritical']}</option>\n";
  1501. }
  1502. $html .= "</select>\n";
  1503. return $html;
  1504. }
  1505. /**
  1506. * Return HTML for a select box for accepting yes/no. The given user's accepting status is displayed.
  1507. * @author Ivan Lucas
  1508. * @param string $name. Name attribute
  1509. * @param int $userid. The user ID to check
  1510. * @returns string. HTML
  1511. */
  1512. function accepting_drop_down($name, $userid)
  1513. {
  1514. if (user_accepting($userid) == "Yes")
  1515. {
  1516. $html = "<select name=\"$name\">\n";
  1517. $html .= "<option selected='selected' value=\"Yes\">{$GLOBALS['strYes']}</option>\n";
  1518. $html .= "<option value=\"No\">{$GLOBALS['strNo']}</option>\n";
  1519. $html .= "</select>\n";
  1520. }
  1521. else
  1522. {
  1523. $html = "<select name=\"$name\">\n";
  1524. $html .= "<option value=\"Yes\">{$GLOBALS['strYes']}</option>\n";
  1525. $html .= "<option selected='selected' value=\"No\">{$GLOBALS['strNo']}</option>\n";
  1526. $html .= "</select>\n";
  1527. }
  1528. return $html;
  1529. }
  1530. /**
  1531. * Return HTML for a select box for escalation path
  1532. * @param string $name. Name attribute
  1533. * @param int $userid. The escalation path ID to pre-select
  1534. * @returns string. HTML
  1535. */
  1536. function escalation_path_drop_down($name, $id)
  1537. {
  1538. global $dbEscalationPaths;
  1539. $sql = "SELECT id, name FROM `{$dbEscalationPaths}` ";
  1540. $sql .= "ORDER BY name ASC";
  1541. $result = mysql_query($sql);
  1542. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  1543. $html = "<select name='{$name}' id='{$name}' >";
  1544. $html .= "<option selected='selected' value='0'>{$GLOBALS['strNone']}</option>\n";
  1545. while ($path = mysql_fetch_object($result))
  1546. {
  1547. $html .= "<option value='{$path->id}'";
  1548. if ($path->id ==$id)
  1549. {
  1550. $html .= " selected='selected'";
  1551. }
  1552. $html .= ">{$path->name}</option>\n";
  1553. }
  1554. $html .= "</select>\n";
  1555. return $html;
  1556. }
  1557. /**
  1558. * Returns a string representing the name of
  1559. * the given priority. Returns an empty string if the
  1560. * priority does not exist.
  1561. * @author Ivan Lucas
  1562. * @param int $id. Priority ID, higher the number higher the priority
  1563. * @param bool $syslang. (optional) Uses system language when set to TRUE otherwise
  1564. * uses user language (default)
  1565. * @returns string.
  1566. */
  1567. function priority_name($id, $syslang = FALSE)
  1568. {
  1569. switch ($id)
  1570. {
  1571. case 1:
  1572. if (!$syslang) $value = $GLOBALS['strLow'];
  1573. else $value = $_SESSION['syslang']['strLow'];
  1574. break;
  1575. case 2:
  1576. if (!$syslang) $value = $GLOBALS['strMedium'];
  1577. else $value = $_SESSION['syslang']['strMedium'];
  1578. break;
  1579. case 3:
  1580. if (!$syslang) $value = $GLOBALS['strHigh'];
  1581. else $value = $_SESSION['syslang']['strHigh'];
  1582. break;
  1583. case 4:
  1584. if (!$syslang) $value = $GLOBALS['strCritical'];
  1585. else $value = $_SESSION['syslang']['strCritical'];
  1586. break;
  1587. case '':
  1588. if (!$sylang) $value = $GLOBALS['strNotSet'];
  1589. else $value = $_SESSION['syslang']['strNotSet'];
  1590. break;
  1591. default:
  1592. if (!$syslang) $value = $GLOBALS['strUnknown'];
  1593. else $value = $_SESSION['syslang']['strUnknown'];
  1594. break;
  1595. }
  1596. return $value;
  1597. }
  1598. // Returns HTML for an icon to indicate priority
  1599. function priority_icon($id)
  1600. {
  1601. global $CONFIG;
  1602. switch ($id)
  1603. {
  1604. case 1: $html = "<img src='{$CONFIG['application_webpath']}images/low_priority.gif' width='10' height='16' alt='{$GLOBALS['strLowPriority']}' title='{$GLOBALS['strLowPriority']}' />"; break;
  1605. case 2: $html = "<img src='{$CONFIG['application_webpath']}images/med_priority.gif' width='10' height='16' alt='{$GLOBALS['strMediumPriority']}' title='{$GLOBALS['strMediumPriority']}' />"; break;
  1606. case 3: $html = "<img src='{$CONFIG['application_webpath']}images/high_priority.gif' width='10' height='16' alt='{$GLOBALS['strHighPriority']}' title='{$GLOBALS['strHighPriority']}' />"; break;
  1607. case 4: $html = "<img src='{$CONFIG['application_webpath']}images/crit_priority.gif' width='16' height='16' alt='{$GLOBALS['strCriticalPriority']}' title='{$GLOBALS['strCriticalPriority']}' />"; break;
  1608. default: $html = '?'; break;
  1609. }
  1610. return $html;
  1611. }
  1612. /**
  1613. * Returns an array of fields from the most recent update record for a given incident id
  1614. * @author Ivan Lucas
  1615. * @param int $id An incident ID
  1616. * @returns array
  1617. */
  1618. function incident_lastupdate($id)
  1619. {
  1620. // Find the most recent update
  1621. $sql = "SELECT userid, type, sla, currentowner, currentstatus, LEFT(bodytext,500) AS body, timestamp, nextaction, id ";
  1622. $sql .= "FROM `{$GLOBALS['dbUpdates']}` WHERE incidentid='{$id}' AND bodytext != '' ORDER BY timestamp DESC, id DESC LIMIT 1";
  1623. $result = mysql_query($sql);
  1624. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  1625. if (mysql_num_rows($result) == 0)
  1626. {
  1627. trigger_error("Zero records while retrieving incident last update for incident {$id}",E_USER_WARNING);
  1628. }
  1629. else
  1630. {
  1631. $update = mysql_fetch_array($result);
  1632. mysql_free_result($result);
  1633. // Remove Tags from update Body
  1634. $update['body'] = trim($update['body']);
  1635. $update['body'] = $update['body'];
  1636. return array($update['userid'], $update['type'] ,$update['currentowner'], $update['currentstatus'], $update['body'], $update['timestamp'], $update['nextaction'], $update['id']);
  1637. }
  1638. }
  1639. /**
  1640. * Returns a string containing the body of the first update (that is visible to customer)
  1641. * in a format suitable for including in an email
  1642. * @author Ivan Lucas
  1643. * @param int $id An incident ID
  1644. */
  1645. function incident_firstupdate($id)
  1646. {
  1647. $sql = "SELECT bodytext FROM `{$GLOBALS['dbUpdates']}` WHERE incidentid='$id' AND customervisibility='show' ORDER BY timestamp ASC, id ASC LIMIT 1";
  1648. $result = mysql_query($sql);
  1649. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  1650. if (mysql_num_rows($result) >= 1)
  1651. {
  1652. list($bodytext) = mysql_fetch_row($result);
  1653. $bodytext = strip_tags($bodytext);
  1654. }
  1655. else
  1656. {
  1657. $bodytext = '';
  1658. }
  1659. return $bodytext;
  1660. }
  1661. /**
  1662. * Converts an incident status ID to an internationalised status string
  1663. * @author Ivan Lucas
  1664. * @param int $id. incident status ID
  1665. * @param string $type. 'internal' or 'external', where external means customer/client facing
  1666. * @returns string Internationalised incident status.
  1667. * Or empty string if the ID is not recognised.
  1668. * @note The incident status database table must contain i18n keys.
  1669. */
  1670. function incidentstatus_name($id, $type='internal')
  1671. {
  1672. global $dbIncidentStatus;
  1673. if ($type == 'external')
  1674. {
  1675. $type = 'ext_name';
  1676. }
  1677. else
  1678. {
  1679. $type = 'name';
  1680. }
  1681. $sql = "SELECT {$type} FROM `{$dbIncidentStatus}` WHERE id='{$id}'";
  1682. $result = mysql_query($sql);
  1683. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  1684. if (mysql_num_rows($result) == 0)
  1685. {
  1686. $name = '';
  1687. }
  1688. else
  1689. {
  1690. $incidentstatus = mysql_fetch_assoc($result);
  1691. $name = $GLOBALS[$incidentstatus[$type]];
  1692. }
  1693. return $name;
  1694. }
  1695. function closingstatus_name($id)
  1696. {
  1697. global $dbClosingStatus;
  1698. if ($id != '')
  1699. {
  1700. $closingstatus = db_read_column('name', $GLOBALS['dbClosingStatus'], $id);
  1701. }
  1702. else
  1703. {
  1704. $closingstatus = 'strUnknown';
  1705. }
  1706. return ($GLOBALS[$closingstatus]);
  1707. }
  1708. /**
  1709. * A drop down to select from a list of open incidents
  1710. * optionally filtered by contactid
  1711. * @author Ivan Lucas
  1712. * @param string $name The name attribute for the HTML select
  1713. * @param int $id The value to select by default (not implemented yet)
  1714. * @param int $contactid Filter the list to show incidents from a single
  1715. contact
  1716. * @returns string HTML
  1717. */
  1718. function incident_drop_down($name, $id, $contactid = 0)
  1719. {
  1720. global $dbIncidents;
  1721. $html = '';
  1722. $sql = "SELECT * FROM `{$dbIncidents}` WHERE status != ".STATUS_CLOSED . " ";
  1723. if ($contactid > 0) $sql .= "AND contact = {$contactid}";
  1724. $result = mysql_query($sql);
  1725. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  1726. if (mysql_num_rows($result) > 0)
  1727. {
  1728. $html = "<select id='{$name}' name='{$name}' {$select}>\n";
  1729. while ($incident = mysql_fetch_object($result))
  1730. {
  1731. // FIXME unfinished
  1732. $html .= "<option value='{$incident->id}'>[{$incident->id}] - ";
  1733. $html .= "{$incident->title}</option>";
  1734. }
  1735. $html .= "</select>";
  1736. }
  1737. else
  1738. {
  1739. $html = "<input type='text' name='{$name}' value='' size='10' maxlength='12' />";
  1740. }
  1741. return $html;
  1742. }
  1743. /* Returns a string representing the name of */
  1744. /* the given user status. Returns an empty string if the */
  1745. /* status does not exist. */
  1746. function userstatus_name($id)
  1747. {
  1748. $status = db_read_column('name', $GLOBALS['dbUserStatus'], $id);
  1749. return $GLOBALS[$status];
  1750. }
  1751. /* Returns a string representing the name of */
  1752. /* the given product. Returns an empty string if the product */
  1753. /* does not exist. */
  1754. function product_name($id)
  1755. {
  1756. return db_read_column('name', $GLOBALS['dbProducts'], $id);
  1757. }
  1758. /**
  1759. * Formats a given number of seconds into a readable string showing days, hours and minutes.
  1760. * @author Ivan Lucas
  1761. * @param int $seconds number of seconds
  1762. * @param bool $showseconds bool If TRUE and $seconds is less than 60 the function returns 1 minute.
  1763. * @returns string Readable date/time
  1764. */
  1765. function format_seconds($seconds, $showseconds = FALSE)
  1766. {
  1767. global $str1Year, $str1Hour, $str1Minute, $str1Day, $str1Month, $strXSeconds, $str1Second;
  1768. global $strXHours, $strXMinutes, $strXDays, $strXMonths, $strXYears;
  1769. if ($seconds <= 0)
  1770. {
  1771. return sprintf($strXMinutes, 0);
  1772. }
  1773. elseif ($seconds <= 60 AND $seconds >= 1 AND $showseconds == FALSE)
  1774. {
  1775. return $str1Minute;
  1776. }
  1777. elseif ($seconds < 60 AND $seconds >= 1 AND $showseconds == TRUE)
  1778. {
  1779. if ($seconds == 1)
  1780. {
  1781. return $str1Second;
  1782. }
  1783. else
  1784. {
  1785. return sprintf($strXSeconds, $seconds);
  1786. }
  1787. }
  1788. else
  1789. {
  1790. $years = floor($seconds / ( 2629800 * 12));
  1791. $remainder = ($seconds % ( 2629800 * 12));
  1792. $months = floor($remainder / 2629800);
  1793. $remainder = ($seconds % 2629800);
  1794. $days = floor($remainder / 86400);
  1795. $remainder = ($remainder % 86400);
  1796. $hours = floor($remainder / 3600);
  1797. $remainder = ($remainder % 3600);
  1798. $minutes = floor($remainder / 60);
  1799. if ($years > 0)
  1800. {
  1801. if ($years == 1)
  1802. {
  1803. $return_string .= $str1Year.' ';
  1804. }
  1805. else
  1806. {
  1807. $return_string .= sprintf($strXYears, $years).' ';
  1808. }
  1809. }
  1810. if ($months > 0 AND $years < 2)
  1811. {
  1812. if ($months == 1)
  1813. {
  1814. $return_string .= $str1Month." ";
  1815. }
  1816. else
  1817. {
  1818. $return_string .= sprintf($strXMonths, $months).' ';
  1819. }
  1820. }
  1821. if ($days > 0 AND $months < 6)
  1822. {
  1823. if ($days == 1)
  1824. {
  1825. $return_string .= $str1Day." ";
  1826. }
  1827. else
  1828. {
  1829. $return_string .= sprintf($strXDays, $days)." ";
  1830. }
  1831. }
  1832. if ($months < 1 AND $days < 7 AND $hours > 0)
  1833. {
  1834. if ($hours == 1)
  1835. {
  1836. $return_string .= $str1Hour." ";
  1837. }
  1838. else
  1839. {
  1840. $return_string .= sprintf($strXHours, $hours)." ";
  1841. }
  1842. }
  1843. elseif ($months < 1 AND $days < 1 AND $hours > 0)
  1844. {
  1845. if ($minutes == 1)
  1846. {
  1847. $return_string .= $str1Minute." ";
  1848. }
  1849. elseif ($minutes > 1)
  1850. {
  1851. $return_string .= sprintf($strXMinutes, $minutes)." ";
  1852. }
  1853. }
  1854. if ($months < 1 AND $days < 1 AND $hours < 1)
  1855. {
  1856. if ($minutes <= 1)
  1857. {
  1858. $return_string .= $str1Minute." ";
  1859. }
  1860. else
  1861. {
  1862. $return_string .= sprintf($strXMinutes, $minutes)." ";
  1863. }
  1864. }
  1865. $return_string = trim($return_string);
  1866. if (empty($return_string)) $return_string = "({$seconds})";
  1867. return $return_string;
  1868. }
  1869. }
  1870. /**
  1871. * Return a string containing the time remaining as working days/hours/minutes (eg. 9am - 5pm)
  1872. * @author Ivan Lucas
  1873. * @returns string. Length of working time, in readable days, hours and minutes
  1874. * @note The working day is calculated using the $CONFIG['end_working_day'] and
  1875. * $CONFIG['start_working_day'] config variables
  1876. */
  1877. function format_workday_minutes($minutes)
  1878. {
  1879. global $CONFIG, $strXMinutes, $str1Minute, $strXHours, $strXHour;
  1880. global $strXWorkingDay, $strXWorkingDays;
  1881. $working_day_mins = ($CONFIG['end_working_day'] - $CONFIG['start_working_day']) / 60;
  1882. $days = floor($minutes / $working_day_mins);
  1883. $remainder = ($minutes % $working_day_mins);
  1884. $hours = floor($remainder / 60);
  1885. $minutes = floor($remainder % 60);
  1886. if ($days == 1)
  1887. {
  1888. $time = sprintf($strXWorkingDay, $days);
  1889. }
  1890. elseif ($days > 1)
  1891. {
  1892. $time = sprintf($strXWorkingDays, $days);
  1893. }
  1894. if ($days <= 3 AND $hours == 1)
  1895. {
  1896. $time .= " ".sprintf($strXHour, $hours);
  1897. }
  1898. elseif ($days <= 3 AND $hours > 1)
  1899. {
  1900. $time .= " ".sprintf($strXHours, $hours);
  1901. }
  1902. elseif ($days > 3 AND $hours >= 1)
  1903. {
  1904. $time = "&gt; ".$time;
  1905. }
  1906. if ($days < 1 AND $hours < 8 AND $minutes == 1)
  1907. {
  1908. $time .= " ".$str1Minute;
  1909. }
  1910. elseif ($days < 1 AND $hours < 8 AND $minutes > 1)
  1911. {
  1912. $time .= " ".sprintf($strXMinutes, $minutes);
  1913. }
  1914. if ($days == 1 AND $hours < 8 AND $minutes == 1)
  1915. {
  1916. $time .= " ".$str1Minute;
  1917. }
  1918. elseif ($days == 1 AND $hours < 8 AND $minutes > 1)
  1919. {
  1920. $time .= " ".sprintf($strXMinutes, $minutes);
  1921. }
  1922. $time = trim($time);
  1923. return $time;
  1924. }
  1925. /**
  1926. * Make a readable and friendly date, i.e. say Today, or Yesterday if it is
  1927. * @author Ivan Lucas
  1928. * @param int $date a UNIX timestamp
  1929. * @returns string. Date in a readable friendly format
  1930. * @note See also readable_date() dupe?
  1931. */
  1932. function format_date_friendly($date)
  1933. {
  1934. global $CONFIG, $now;
  1935. if (ldate('dmy', $date) == ldate('dmy', time()))
  1936. {
  1937. $datestring = "{$GLOBALS['strToday']} @ ".ldate($CONFIG['dateformat_time'], $date);
  1938. }
  1939. elseif (ldate('dmy', $date) == ldate('dmy', (time() - 86400)))
  1940. {
  1941. $datestring = "{$GLOBALS['strYesterday']} @ ".ldate($CONFIG['dateformat_time'], $date);
  1942. }
  1943. elseif ($date < $now-86400 AND
  1944. $date > $now-(86400*6))
  1945. {
  1946. $datestring = ldate('l', $date)." @ ".ldate($CONFIG['dateformat_time'], $date);
  1947. }
  1948. else
  1949. {
  1950. $datestring = ldate($CONFIG['dateformat_datetime'], $date);
  1951. }
  1952. return ($datestring);
  1953. }
  1954. /* calculates the value of the unix timestamp */
  1955. /* which is the number of given days, hours and minutes from */
  1956. /* the current time. */
  1957. function calculate_time_of_next_action($days, $hours, $minutes)
  1958. {
  1959. $now = time();
  1960. $return_value = $now + ($days * 86400) + ($hours * 3600) + ($minutes * 60);
  1961. return ($return_value);
  1962. }
  1963. /**
  1964. * Retrieves the service level ID of a given maintenance contract
  1965. * @author Ivan Lucas
  1966. * @param int $maintid. Contract ID
  1967. * @returns. int Service Level ID
  1968. * @deprecated
  1969. * @note Service level ID's are DEPRECATED service level tags should be used in favour of service level ID's
  1970. */
  1971. function maintenance_servicelevel($maintid)
  1972. {
  1973. global $CONFIG, $dbMaintenance;
  1974. $sql = "SELECT servicelevelid FROM `{$dbMaintenance}` WHERE id='{$maintid}' ";
  1975. $result = mysql_query($sql);
  1976. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  1977. if (mysql_num_rows($result) < 1)
  1978. {
  1979. // in case there is no maintenance contract associated with the incident, use default service level
  1980. // if there is a maintenance contract then we should throw an error because there should be
  1981. // service level
  1982. if ($maintid == 0)
  1983. {
  1984. // Convert the default service level tag to an ide and use that
  1985. $servicelevelid = servicelevel_tag2id($CONFIG['default_service_level']);
  1986. }
  1987. }
  1988. else
  1989. {
  1990. list($servicelevelid) = mysql_fetch_row($result);
  1991. }
  1992. return $servicelevelid;
  1993. }
  1994. function maintenance_siteid($id)
  1995. {
  1996. return db_read_column('site', $GLOBALS['dbMaintenance'], $id);
  1997. }
  1998. // Returns the number of remaining incidents given an incident pool id
  1999. // Returns 'Unlimited' if theres no match on ID
  2000. function incidents_remaining($id)
  2001. {
  2002. $remaining = db_read_column('incidentsremaining', $GLOBALS['dbIncidentPools'], $id);
  2003. if (empty($remaining))
  2004. {
  2005. $remaining = '&infin;';
  2006. }
  2007. return $remaining;
  2008. }
  2009. function decrement_free_incidents($siteid)
  2010. {
  2011. global $dbSites;
  2012. $sql = "UPDATE `{$dbSites}` SET freesupport = (freesupport - 1) WHERE id='$siteid'";
  2013. mysql_query($sql);
  2014. if (mysql_affected_rows() < 1)
  2015. {
  2016. trigger_error("No rows affected while updating freesupport",E_USER_ERROR);
  2017. }
  2018. if (mysql_error()) trigger_error(mysql_error(),E_USER_ERROR);
  2019. else return TRUE;
  2020. }
  2021. function increment_incidents_used($maintid)
  2022. {
  2023. global $dbMaintenance;
  2024. $sql = "UPDATE `{$dbMaintenance}` SET incidents_used = (incidents_used + 1) WHERE id='$maintid'";
  2025. mysql_query($sql);
  2026. if (mysql_affected_rows() < 1) trigger_error("No rows affected while updating freesupport",E_USER_ERROR);
  2027. if (mysql_error()) trigger_error(mysql_error(),E_USER_ERROR);
  2028. else return TRUE;
  2029. }
  2030. /**
  2031. * Handle a PHP triggered error
  2032. * @author Ivan Lucas
  2033. * @note Not called directly but triggered by PHP's own error handling
  2034. * and the trigger_error function.
  2035. * @note Parameters as per http://www.php.net/set_error_handler
  2036. * @note This function is not internationalised in order that bugs can
  2037. * be reported to developers and still be sure that they will be
  2038. * understood
  2039. **/
  2040. function sit_error_handler($errno, $errstr, $errfile, $errline, $errcontext)
  2041. {
  2042. global $CONFIG, $sit, $siterrors;
  2043. // if error has been supressed with an @
  2044. if (error_reporting() == 0)
  2045. {
  2046. return;
  2047. }
  2048. $errortype = array(
  2049. E_ERROR => 'Fatal Error',
  2050. E_WARNING => 'Warning',
  2051. E_PARSE => 'Parse Error',
  2052. E_NOTICE => 'Notice',
  2053. E_CORE_ERROR => 'Core Error',
  2054. E_CORE_WARNING => 'Core Warning',
  2055. E_COMPILE_ERROR => 'Compile Error',
  2056. E_COMPILE_WARNING => 'Compile Warning',
  2057. E_USER_ERROR => 'Application Error',
  2058. E_USER_WARNING => 'Application Warning',
  2059. E_USER_NOTICE => 'Application Notice');
  2060. if (defined('E_STRICT')) $errortype[E_STRICT] = 'Strict Runtime notice';
  2061. $trace_errors = array(E_ERROR, E_USER_ERROR);
  2062. $user_errors = E_USER_ERROR | E_USER_WARNING | E_USER_NOTICE;
  2063. $system_errors = E_ERROR | E_WARNING | E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_COMPILE_WARNING;
  2064. $warnings = E_WARNING | E_USER_WARNING | E_CORE_WARNING | E_COMPILE_WARNING;
  2065. $notices = E_NOTICE | E_USER_NOTICE;
  2066. if (($errno & $user_errors) OR ($errno & $system_errors))
  2067. {
  2068. if (empty($CONFIG['error_logfile']) === FALSE AND is_writable($CONFIG['error_logfile']) === TRUE)
  2069. {
  2070. $displayerrors = FALSE;
  2071. }
  2072. else
  2073. {
  2074. $displayerrors = TRUE;
  2075. }
  2076. if ($errno & $notices) $class = 'info';
  2077. elseif ($errno & $warnings) $class = 'warning';
  2078. else $class='error';
  2079. $backtrace = debug_backtrace();
  2080. if (php_sapi_name() != 'cli')
  2081. {
  2082. $tracelog = '';
  2083. if ($displayerrors)
  2084. {
  2085. echo "<p class='{$class}'><strong>{$errortype[$errno]} [{$errno}]</strong><br />";
  2086. echo "{$errstr} in {$errfile} @ line {$errline}";
  2087. if ($CONFIG['debug']) echo "<br /><strong>Backtrace</strong>:";
  2088. }
  2089. foreach ($backtrace AS $trace)
  2090. {
  2091. if (!empty($trace['file']))
  2092. {
  2093. if ($CONFIG['debug'] AND $displayerrors) echo "<br />{$trace['file']} @ line {$trace['line']}";
  2094. $tracelog .= "{$trace['file']} @ line {$trace['line']}";
  2095. if (!empty($trace['function']))
  2096. {
  2097. $tracelog .= " {$trace['function']}()";
  2098. if ($displayerrors) echo " {$trace['function']}() ";
  2099. // foreach ($trace['args'] AS $arg)
  2100. // {
  2101. // echo "$arg &bull; ";
  2102. // }
  2103. }
  2104. $tracelog .= "\n";
  2105. }
  2106. }
  2107. if ($errno != E_NOTICE)
  2108. {
  2109. $logentry = " {$errortype[$errno]} [{$errno}] {$errstr} (in line {$errline} of file {$errfile})\n";
  2110. }
  2111. if ($errno==E_ERROR
  2112. || $errno==E_USER_ERROR
  2113. || $errno==E_CORE_ERROR
  2114. || $errno==E_CORE_WARNING
  2115. || $errno==E_COMPILE_ERROR
  2116. || $errno==E_COMPILE_WARNING)
  2117. {
  2118. $logentry .= "Context: [CONTEXT-BEGIN]\n".print_r($errcontext, TRUE)."\n[CONTEXT-END]\n----------\n\n";
  2119. $siterrors++;
  2120. }
  2121. debug_log($logentry);
  2122. if ($displayerrors)
  2123. {
  2124. echo "</p>";
  2125. // Tips, to help diagnose errors
  2126. if (strpos($errstr, 'Unknown column') !== FALSE OR
  2127. preg_match("/Table '(.*)' doesn't exist/", $errstr))
  2128. {
  2129. echo "<p class='tip'>The SiT schema may need updating to fix this problem.";
  2130. if (user_permission($sit[2], 22)) echo "Visit <a href='setup.php'>Setup</a>"; // Only show this to admin
  2131. echo "</p>";
  2132. }
  2133. if (strpos($errstr, 'headers already sent') !== FALSE)
  2134. {
  2135. echo "<p class='tip'>This warning may be caused by a problem that occurred before the ";
  2136. echo "page was displayed, or sometimes by a syntax error or ";
  2137. echo "extra whitespace in your config file.</p>";
  2138. }
  2139. if (strpos($errstr, 'You have an error in your SQL syntax') !== FALSE OR
  2140. strpos($errstr, 'Query Error Incorrect table name') !== FALSE)
  2141. {
  2142. echo "<p class='tip'>You may have found a bug in SiT, please <a href=\"{$CONFIG['bugtracker_url']}\">report it</a>.</p>";
  2143. }
  2144. }
  2145. }
  2146. else
  2147. {
  2148. debug_log("ERROR: {$errortype[$errno]} {$errstr} in {$errfile} at line {$errline}\n");
  2149. if (!empty($tracelog)) debug_log("ERROR: Backtrace:\n{$tracelog}\n");
  2150. }
  2151. }
  2152. }
  2153. /**
  2154. * Write an entry to the configured error logfile
  2155. * @author Ivan Lucas
  2156. * @param string $logentry. A line, or lines to write to the log file
  2157. * (with newlines \n)
  2158. * @param bool $debugmodeonly. Only write an entry if debug mode is TRUE
  2159. * @retval bool TRUE log entry written
  2160. * @retval bool FALSE log entry not written
  2161. */
  2162. function debug_log($logentry, $debugmodeonly = FALSE)
  2163. {
  2164. global $CONFIG;
  2165. if ($debugmodeonly == FALSE
  2166. OR ($debugmodeonly == TRUE AND $CONFIG['debug'] == TRUE))
  2167. {
  2168. $logentry = $_SERVER["SCRIPT_NAME"] . ' ' .$logentry;
  2169. if (substr($logentry, -1) != "\n") $logentry .= "\n";
  2170. if (!empty($CONFIG['error_logfile']))
  2171. {
  2172. if (is_writable($CONFIG['error_logfile']))
  2173. {
  2174. $fp = fopen($CONFIG['error_logfile'], 'a+');
  2175. if ($fp)
  2176. {
  2177. fwrite($fp, date('c').' '.strip_tags($logentry));
  2178. fclose($fp);
  2179. }
  2180. else
  2181. {
  2182. echo "<p class='error'>Could not log message to error_logfile</p>";
  2183. return FALSE;
  2184. }
  2185. return TRUE;
  2186. }
  2187. }
  2188. else
  2189. {
  2190. return FALSE;
  2191. }
  2192. }
  2193. else return TRUE;
  2194. }
  2195. /**
  2196. * Generates a HTML drop down of sites within SiT!
  2197. * @param string $name The name of the field
  2198. * @param int $id The ID of the selected item
  2199. * @param bool $required Whether this is a mandetory field, defaults to false
  2200. * @param bool $showinactive Whether to show the sites marked inactive, defaults to false
  2201. * @return string The HTML for the drop down
  2202. */
  2203. function site_drop_down($name, $id, $required = FALSE, $showinactive = FALSE)
  2204. {
  2205. global $dbSites;
  2206. $sql = "SELECT id, name, department FROM `{$dbSites}` ";
  2207. if (!$showinactive) $sql .= "WHERE active = 'true' ";
  2208. $sql .= "ORDER BY name ASC";
  2209. $result = mysql_query($sql);
  2210. $html = "<select name='{$name}'";
  2211. if ($required)
  2212. {
  2213. $html .= " class='required' ";
  2214. }
  2215. $html .= ">\n";
  2216. if ($id == 0)
  2217. {
  2218. $html .="<option selected='selected' value='0'></option>\n";
  2219. }
  2220. while ($sites = mysql_fetch_object($result))
  2221. {
  2222. $text = $sites->name;
  2223. if (!empty($sites->department))
  2224. {
  2225. $text.= ", ".$sites->department;
  2226. }
  2227. if (strlen($text) >= 55)
  2228. {
  2229. $text = substr(trim($text), 0, 55)."&hellip;";
  2230. }
  2231. else
  2232. {
  2233. $text = $text;
  2234. }
  2235. $html .= "<option ";
  2236. if ($sites->id == $id)
  2237. {
  2238. $html .= "selected='selected' ";
  2239. }
  2240. $html .= "value='{$sites->id}'>{$text}</option>\n";
  2241. }
  2242. $html .= "</select>\n";
  2243. return $html;
  2244. }
  2245. function site_name($id)
  2246. {
  2247. $sitename = db_read_column('name', $GLOBALS['dbSites'], $id);
  2248. if (empty($sitename))
  2249. {
  2250. $sitename = $GLOBALS['strUnknown'];
  2251. }
  2252. return ($sitename);
  2253. }
  2254. /**
  2255. * prints the HTML for a drop down list of maintenance contracts
  2256. * @param string $name. name of the drop down box
  2257. * @param int $id. the contract id to preselect
  2258. * @param int $siteid. Show records from this SiteID only, blank for all sites
  2259. * @param array $excludes. Hide contracts with ID's in this array
  2260. * @param bool $return. Whether to return to HTML or echo
  2261. * @param bool $showonlyactive. True show only active (with a future expiry date), false shows all
  2262. */
  2263. function maintenance_drop_down($name, $id, $siteid = '', $excludes = '', $return = FALSE, $showonlyactive = FALSE, $adminid = '')
  2264. {
  2265. global $GLOBALS, $now;
  2266. // TODO make maintenance_drop_down a hierarchical selection box sites/contracts
  2267. // extract all maintenance contracts
  2268. $sql = "SELECT s.name AS sitename, p.name AS productname, m.id AS id ";
  2269. $sql .= "FROM `{$GLOBALS['dbMaintenance']}` AS m, `{$GLOBALS['dbSites']}` AS s, `{$GLOBALS['dbProducts']}` AS p ";
  2270. $sql .= "WHERE site = s.id AND product = p.id ";
  2271. if (!empty($siteid)) $sql .= "AND s.id = {$siteid} ";
  2272. if ($showonlyactive)
  2273. {
  2274. $sql .= "AND (m.expirydate > {$now} OR m.expirydate = -1) ";
  2275. }
  2276. if ($adminid != '')
  2277. {
  2278. $sql .= "AND admincontact = '{$adminid}' ";
  2279. }
  2280. $sql .= "ORDER BY s.name ASC";
  2281. $result = mysql_query($sql);
  2282. $results = 0;
  2283. // print HTML
  2284. $html .= "<select name='{$name}'>";
  2285. if ($id == 0 AND $results > 0)
  2286. {
  2287. $html .= "<option selected='selected' value='0'></option>\n";
  2288. }
  2289. while ($maintenance = mysql_fetch_object($result))
  2290. {
  2291. if (!is_array($excludes) OR (is_array($excludes) AND !in_array($maintenance->id, $excludes)))
  2292. {
  2293. $html .= "<option ";
  2294. if ($maintenance->id == $id)
  2295. {
  2296. $html .= "selected='selected' ";
  2297. }
  2298. $html .= "value='{$maintenance->id}'>{$maintenance->sitename} | {$maintenance->productname}</option>";
  2299. $html .= "\n";
  2300. $results++;
  2301. }
  2302. }
  2303. if ($results == 0)
  2304. {
  2305. $html .= "<option>{$GLOBALS['strNoRecords']}</option>";
  2306. }
  2307. $html .= "</select>";
  2308. if ($return)
  2309. {
  2310. return $html;
  2311. }
  2312. else
  2313. {
  2314. echo $html;
  2315. }
  2316. }
  2317. // prints the HTML for a drop down list of resellers, with the given name and with the given id
  2318. // selected. */
  2319. function reseller_drop_down($name, $id)
  2320. {
  2321. global $dbResellers;
  2322. $sql = "SELECT id, name FROM `{$dbResellers}` ORDER BY name ASC";
  2323. $result = mysql_query($sql);
  2324. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  2325. // print HTML
  2326. echo "<select name='{$name}'>";
  2327. if ($id == 0 OR empty($id))
  2328. {
  2329. echo "<option selected='selected' value='0'></option>\n";
  2330. }
  2331. else
  2332. {
  2333. echo "<option value='0'></option>\n";
  2334. }
  2335. while ($resellers = mysql_fetch_object($result))
  2336. {
  2337. echo "<option ";
  2338. if ($resellers->id == $id)
  2339. {
  2340. echo "selected='selected' ";
  2341. }
  2342. echo "value='{$resellers->id}'>{$resellers->name}</option>";
  2343. echo "\n";
  2344. }
  2345. echo "</select>";
  2346. }
  2347. // prints the HTML for a drop down list of
  2348. // licence types, with the given name and with the given id
  2349. // selected.
  2350. function licence_type_drop_down($name, $id)
  2351. {
  2352. global $dbLicenceTypes;
  2353. $sql = "SELECT id, name FROM `{$dbLicenceTypes}` ORDER BY name ASC";
  2354. $result = mysql_query($sql);
  2355. // print HTML
  2356. echo "<select name='{$name}'>";
  2357. if ($id == 0)
  2358. {
  2359. echo "<option selected='selected' value='0'></option>\n";
  2360. }
  2361. while ($licencetypes = mysql_fetch_object($result))
  2362. {
  2363. echo "<option ";
  2364. if ($licencetypes->id == $id)
  2365. {
  2366. echo "selected='selected' ";
  2367. }
  2368. echo "value='{$licencetypes->id}'>{$licencetypes->name}</option>";
  2369. echo "\n";
  2370. }
  2371. echo "</select>";
  2372. }
  2373. /**
  2374. * @author Ivan Lucas
  2375. */
  2376. function countdayincidents($day, $month, $year)
  2377. {
  2378. // Counts the number of incidents opened on a specified day
  2379. global $dbIncidents;
  2380. $unixstartdate = mktime(0,0,0,$month,$day,$year);
  2381. $unixenddate = mktime(23,59,59,$month,$day,$year);
  2382. $sql = "SELECT count(id) FROM `{$dbIncidents}` ";
  2383. $sql .= "WHERE opened BETWEEN '$unixstartdate' AND '$unixenddate' ";
  2384. $result = mysql_query($sql);
  2385. list($count) = mysql_fetch_row($result);
  2386. mysql_free_result($result);
  2387. return $count;
  2388. }
  2389. /**
  2390. * @author Ivan Lucas
  2391. */
  2392. function countdayclosedincidents($day, $month, $year)
  2393. {
  2394. // Counts the number of incidents closed on a specified day
  2395. global $dbIncidents;
  2396. $unixstartdate = mktime(0,0,0,$month,$day,$year);
  2397. $unixenddate = mktime(23,59,59,$month,$day,$year);
  2398. $sql = "SELECT COUNT(id) FROM `{$dbIncidents}` ";
  2399. $sql .= "WHERE closed BETWEEN '$unixstartdate' AND '$unixenddate' ";
  2400. $result = mysql_query($sql);
  2401. list($count) = mysql_fetch_row($result);
  2402. mysql_free_result($result);
  2403. return $count;
  2404. }
  2405. /**
  2406. * @author Ivan Lucas
  2407. */
  2408. function countdaycurrentincidents($day, $month, $year)
  2409. {
  2410. global $dbIncidents;
  2411. // Counts the number of incidents currently open on a specified day
  2412. $unixstartdate = mktime(0,0,0,$month,$day,$year);
  2413. $unixenddate = mktime(23,59,59,$month,$day,$year);
  2414. $sql = "SELECT COUNT(id) FROM `{$dbIncidents}` ";
  2415. $sql .= "WHERE opened <= '$unixenddate' AND closed >= '$unixstartdate' ";
  2416. $result = mysql_query($sql);
  2417. list($count) = mysql_fetch_row($result);
  2418. mysql_free_result($result);
  2419. return $count;
  2420. }
  2421. /**
  2422. * Inserts an entry into the Journal table and marks the user online
  2423. * @author Ivan Lucas, Kieran Hogg
  2424. * @param int $loglevel The log level required for this event to be logged
  2425. * @param string $event Text title for the event
  2426. * @param string $bodytext Text describing the event in detail
  2427. * @param int $journaltype One of the defined journal types
  2428. * @param int $refid An ID to relate to data, the table this ID is for
  2429. depends on the journal type used
  2430. * @retval TRUE success, entry logged
  2431. * @retval FALSE failure. entry not logged
  2432. * @note Produces an audit log
  2433. */
  2434. function journal($loglevel, $event, $bodytext, $journaltype, $refid)
  2435. {
  2436. global $CONFIG, $sit, $dbJournal;
  2437. // Journal Types
  2438. // 1 = Logon/Logoff
  2439. // 2 = Support Incidents
  2440. // 3 = -Unused-
  2441. // 4 = Sites
  2442. // 5 = Contacts
  2443. // 6 = Admin
  2444. // 7 = User Management
  2445. // Logging Level
  2446. // 0 = No logging
  2447. // 1 = Minimal Logging
  2448. // 2 = Normal Logging
  2449. // 3 = Full Logging
  2450. // 4 = Max Debug Logging
  2451. $bodytext = mysql_real_escape_string($bodytext);
  2452. if ($loglevel <= $CONFIG['journal_loglevel'])
  2453. {
  2454. $sql = "INSERT INTO `{$dbJournal}` ";
  2455. $sql .= "(userid, event, bodytext, journaltype, refid) ";
  2456. $sql .= "VALUES ('".$_SESSION['userid']."', '$event', '$bodytext', '$journaltype', '$refid') ";
  2457. $result = mysql_query($sql);
  2458. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  2459. return TRUE;
  2460. }
  2461. else
  2462. {
  2463. // Below minimum log level - do nothing
  2464. return FALSE;
  2465. }
  2466. }
  2467. /**
  2468. Send an email from SiT
  2469. * @param string $to. Destination email address
  2470. * @param string $from. Source email address
  2471. * @param string $subject. Email subject line
  2472. * @param string $body. Email body text
  2473. * @param string $replyto. (optional) Address to send reply to
  2474. * @param string $cc. (optional) Carbon copy address
  2475. * @param string $bcc. (optional) Blind carbon copy address
  2476. * @returns The return value from PHP mail() function or TRUE when in Demo mode
  2477. * @note Returns TRUE but does not actually send mail when SiT is in Demo mode
  2478. */
  2479. function send_email($to, $from, $subject, $body, $replyto='', $cc='', $bcc='')
  2480. {
  2481. global $CONFIG, $application_version_string;
  2482. $crlf = "\r\n";
  2483. if (empty($to)) trigger_error('Empty TO address in email', E_USER_WARNING);
  2484. $extra_headers = "From: {$from}" . $crlf;
  2485. if (!empty($replyto)) $extra_headers .= "Reply-To: {$replyto}" . $crlf;
  2486. if (!empty($email_cc))
  2487. {
  2488. $extra_headers .= "CC: {$cc}" . $crlf;
  2489. }
  2490. if (!empty($email_bcc))
  2491. {
  2492. $extra_headers .= "BCC: {$bcc}" . $crlf;
  2493. }
  2494. if (!empty($CONFIG['support_email']))
  2495. {
  2496. $extra_headers .= "Errors-To: {$CONFIG['support_email']}" . $crlf;
  2497. }
  2498. $extra_headers .= "X-Mailer: {$CONFIG['application_shortname']} {$application_version_string}/PHP " . phpversion() . $crlf;
  2499. $extra_headers .= "X-Originating-IP: {$_SERVER['REMOTE_ADDR']}" . $crlf;
  2500. $extra_headers .= "MIME-Version: 1.0" . $crlf;
  2501. $extra_headers .= "Content-type: text/plain; charset={$GLOBALS['i18ncharset']}" . $crlf;
  2502. // $extra_headers .= "\r\n";
  2503. if ($CONFIG['demo'])
  2504. {
  2505. $rtnvalue = TRUE;
  2506. }
  2507. else
  2508. {
  2509. $rtnvalue = mail($to, $subject, $body, $extra_headers);
  2510. }
  2511. return $rtnvalue;
  2512. }
  2513. /**
  2514. * Generates and returns a random alphanumeric password
  2515. * @author Ivan Lucas
  2516. * @note Some characters (0 and 1) are not used to avoid user confusion
  2517. */
  2518. function generate_password($length=8)
  2519. {
  2520. $possible = '0123456789'.'abcdefghijkmnpqrstuvwxyz'.'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.'-';
  2521. // $possible = '23456789'.'abcdefghjkmnpqrstuvwxyz'.'ABCDEFGHJKLMNPQRSTUVWXYZ'.'-';
  2522. // not using 1's 0's etc. to save confusion
  2523. // '-=!&';
  2524. $str = '';
  2525. while (strlen($str) < $length)
  2526. {
  2527. $str .= substr($possible, (rand() % strlen($possible)),1);
  2528. }
  2529. return $str;
  2530. }
  2531. if (!function_exists('list_dir'))
  2532. {
  2533. // returns an array contains all files in a directory and optionally recurses subdirectories
  2534. function list_dir($dirname, $recursive = 1)
  2535. {
  2536. // try to figure out what delimeter is being used (for windows or unix)...
  2537. $delim = (strstr($dirname,"/")) ? "/" : "\\";
  2538. if ($dirname[strlen($dirname)-1] != $delim)
  2539. $dirname .= $delim;
  2540. $handle = opendir($dirname);
  2541. if ($handle == FALSE) trigger_error("Error in list_dir() Problem attempting to open directory: {$dirname}",E_USER_WARNING);
  2542. $result_array = array();
  2543. while ($file = readdir($handle))
  2544. {
  2545. if ($file == '.' || $file == '..')
  2546. {
  2547. continue;
  2548. }
  2549. if (is_dir($dirname.$file) && $recursive)
  2550. {
  2551. $x = list_dir($dirname.$file.$delim);
  2552. $result_array = array_merge($result_array, $x);
  2553. }
  2554. else
  2555. {
  2556. $result_array[] = $dirname.$file;
  2557. }
  2558. }
  2559. closedir($handle);
  2560. if (sizeof($result_array))
  2561. {
  2562. natsort($result_array);
  2563. if ($_SESSION['update_order'] == "desc")
  2564. {
  2565. $result_array = array_reverse($result_array);
  2566. }
  2567. }
  2568. return $result_array;
  2569. }
  2570. }
  2571. if (!function_exists('is_number'))
  2572. {
  2573. function is_number($string)
  2574. {
  2575. $number = TRUE;
  2576. for ($i=0; $i < strlen($string); $i++)
  2577. {
  2578. if (!(ord(substr($string,$i,1)) <= 57 && ord(substr($string,$i,1)) >= 48))
  2579. {
  2580. $number = FALSE;
  2581. }
  2582. }
  2583. return $number;
  2584. }
  2585. }
  2586. // recursive copy from one directory to another
  2587. function rec_copy ($from_path, $to_path)
  2588. {
  2589. if ($from_path == '') trigger_error('Cannot move file', 'from_path not set', E_USER_WARNING);
  2590. if ($to_path == '') trigger_error('Cannot move file', 'to_path not set', E_USER_WARNING);
  2591. $mk = mkdir($to_path, 0700);
  2592. if (!$mk) trigger_error('Failed creating directory: {$to_path}',E_USER_WARNING);
  2593. $this_path = getcwd();
  2594. if (is_dir($from_path))
  2595. {
  2596. chdir($from_path);
  2597. $handle = opendir('.');
  2598. while (($file = readdir($handle)) !== false)
  2599. {
  2600. if (($file != ".") && ($file != ".."))
  2601. {
  2602. if (is_dir($file))
  2603. {
  2604. rec_copy ($from_path.$file."/",
  2605. $to_path.$file."/");
  2606. chdir($from_path);
  2607. }
  2608. if (is_file($file))
  2609. {
  2610. if (!(substr(rtrim($file),strlen(rtrim($file))-8,4) == 'mail'
  2611. || substr(rtrim($file),strlen(rtrim($file))-10,5) == 'part1'
  2612. || substr(rtrim($file),strlen(rtrim($file))-8,4) == '.vcf'))
  2613. {
  2614. copy($from_path.$file, $to_path.$file);
  2615. }
  2616. }
  2617. }
  2618. }
  2619. closedir($handle);
  2620. }
  2621. }
  2622. /**
  2623. * @author Ivan Lucas
  2624. */
  2625. function getattachmenticon($filename)
  2626. {
  2627. global $CONFIG, $iconset;
  2628. // Maybe sometime make this use mime typesad of file extensions
  2629. $ext = strtolower(substr($filename, (strlen($filename)-3) , 3));
  2630. $imageurl = "{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/unknown.png";
  2631. $type_image = "{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/file_image.png";
  2632. $filetype[]="gif"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/image.png";
  2633. $filetype[]="jpg"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/image.png";
  2634. $filetype[]="bmp"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/image.png";
  2635. $filetype[]="png"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/image.png";
  2636. $filetype[]="pcx"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/image.png";
  2637. $filetype[]="xls"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/spreadsheet.png";
  2638. $filetype[]="csv"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/spreadsheet.png";
  2639. $filetype[]="zip"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/tgz.png";
  2640. $filetype[]="arj"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/zip.png";
  2641. $filetype[]="rar"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/rar.png";
  2642. $filetype[]="cab"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/tgz.png";
  2643. $filetype[]="lzh"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/tgz.png";
  2644. $filetype[]="txt"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/txt.png";
  2645. $filetype[]="f90"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/source_f.png";
  2646. $filetype[]="f77"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/source_f.png";
  2647. $filetype[]="inf"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/source.png";
  2648. $filetype[]="ins"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/source.png";
  2649. $filetype[]="adm"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/source.png";
  2650. $filetype[]="f95"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/source_f.png";
  2651. $filetype[]="cpp"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/source_cpp.png";
  2652. $filetype[]="for"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/source_f.png";
  2653. $filetype[]=".pl"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/source_pl.png";
  2654. $filetype[]=".py"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/source_py.png";
  2655. $filetype[]="rtm"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/misc_doc.png";
  2656. $filetype[]="doc"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/wordprocessing.png";
  2657. $filetype[]="rtf"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/wordprocessing.png";
  2658. $filetype[]="wri"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/wordprocessing.png";
  2659. $filetype[]="wri"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/wordprocessing.png";
  2660. $filetype[]="pdf"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/pdf.png";
  2661. $filetype[]="htm"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/html.png";
  2662. $filetype[]="tml"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/html.png";
  2663. $filetype[]="wav"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/sound.png";
  2664. $filetype[]="mp3"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/sound.png";
  2665. $filetype[]="voc"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/sound.png";
  2666. $filetype[]="exe"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/binary.png";
  2667. $filetype[]="com"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/binary.png";
  2668. $filetype[]="nlm"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/binary.png";
  2669. $filetype[]="evt"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/log.png";
  2670. $filetype[]="log"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/log.png";
  2671. $filetype[]="386"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/binary.png";
  2672. $filetype[]="dll"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/binary.png";
  2673. $filetype[]="asc"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/txt.png";
  2674. $filetype[]="asp"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/html.png";
  2675. $filetype[]="avi"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/video.png";
  2676. $filetype[]="bkf"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/tar.png";
  2677. $filetype[]="chm"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/man.png";
  2678. $filetype[]="hlp"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/man.png";
  2679. $filetype[]="dif"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/txt.png";
  2680. $filetype[]="hta"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/html.png";
  2681. $filetype[]="reg"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/resource.png";
  2682. $filetype[]="dmp"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/core.png";
  2683. $filetype[]="ini"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/source.png";
  2684. $filetype[]="jpe"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/image.png";
  2685. $filetype[]="mht"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/html.png";
  2686. $filetype[]="msi"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/binary.png";
  2687. $filetype[]="aot"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/binary.png";
  2688. $filetype[]="pgp"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/binary.png";
  2689. $filetype[]="dbg"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/binary.png";
  2690. $filetype[]="axt"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/source.png"; // zen text
  2691. $filetype[]="rdp"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/binary.png";
  2692. $filetype[]="sig"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/document.png";
  2693. $filetype[]="tif"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/image.png";
  2694. $filetype[]="ttf"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/font_ttf.png";
  2695. $filetype[]="for"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/font_bitmap.png";
  2696. $filetype[]="vbs"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/shellscript.png";
  2697. $filetype[]="vbe"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/shellscript.png";
  2698. $filetype[]="bat"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/shellscript.png";
  2699. $filetype[]="wsf"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/shellscript.png";
  2700. $filetype[]="cmd"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/shellscript.png";
  2701. $filetype[]="scr"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/binary.png";
  2702. $filetype[]="xml"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/xml.png";
  2703. $filetype[]="zap"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/binary.png";
  2704. $filetype[]=".ps"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/postscript.png";
  2705. $filetype[]=".rm"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/real_doc.png";
  2706. $filetype[]="ram"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/real_doc.png";
  2707. $filetype[]="vcf"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/vcard.png";
  2708. $filetype[]="wmf"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/vectorgfx.png";
  2709. $filetype[]="cer"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/document.png";
  2710. $filetype[]="tmp"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/unknown.png";
  2711. $filetype[]="cap"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/binary.png";
  2712. $filetype[]="tr1"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/binary.png";
  2713. $filetype[]=".gz"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/tgz.png";
  2714. $filetype[]="tar"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/tar.png";
  2715. $filetype[]="nfo"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/info.png";
  2716. $filetype[]="pal"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/colorscm.png";
  2717. $filetype[]="iso"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/cdimage.png";
  2718. $filetype[]="jar"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/java_src.png";
  2719. $filetype[]="eml"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/message.png";
  2720. $filetype[]=".sh"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/shellscript.png";
  2721. $filetype[]="bz2"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/tgz.png";
  2722. $filetype[]="out"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/log.png";
  2723. $filetype[]="cfg"; $imgurl[]="{$CONFIG['application_webpath']}images/icons/{$iconset}/32x32/mimetypes/log.png";
  2724. $cnt = count($filetype);
  2725. if ( $cnt > 0 )
  2726. {
  2727. $a = 0;
  2728. $stop = FALSE;
  2729. while ($a < $cnt && $stop == FALSE)
  2730. {
  2731. if ($ext==$filetype[$a])
  2732. {
  2733. $imageurl = $imgurl[$a];
  2734. $stop = TRUE;
  2735. }
  2736. $a++;
  2737. }
  2738. }
  2739. unset ($filetype);
  2740. unset ($imgurl);
  2741. return $imageurl;
  2742. }
  2743. function count_incoming_updates()
  2744. {
  2745. $sql = "SELECT id FROM `{$GLOBALS['dbUpdates']}` WHERE incidentid=0";
  2746. $result = mysql_query($sql);
  2747. $count = mysql_num_rows($result);
  2748. mysql_free_result($result);
  2749. return $count;
  2750. }
  2751. function global_signature()
  2752. {
  2753. $sql = "SELECT signature FROM `{$GLOBALS['dbEmailSig']}` ORDER BY RAND() LIMIT 1";
  2754. $result = mysql_query($sql);
  2755. list($signature) = mysql_fetch_row($result);
  2756. mysql_free_result($result);
  2757. return $signature;
  2758. }
  2759. function holiday_type ($id)
  2760. {
  2761. switch ($id)
  2762. {
  2763. case HOL_HOLIDAY: $holidaytype = $GLOBALS['strHoliday']; break;
  2764. case HOL_SICKNESS: $holidaytype = $GLOBALS['strAbsentSick']; break;
  2765. case HOL_WORKING_AWAY: $holidaytype = $GLOBALS['strWorkingAway']; break;
  2766. case HOL_TRAINING: $holidaytype = $GLOBALS['strTraining']; break;
  2767. case HOL_FREE: $holidaytype = $GLOBALS['strCompassionateLeave']; break;
  2768. case HOL_PUBLIC: $holidaytype = $GLOBALS['strPublicHoliday']; break;
  2769. default: $holidaytype = $GLOBALS['strUnknown']; break;
  2770. }
  2771. return ($holidaytype);
  2772. }
  2773. function holiday_approval_status($approvedid, $approvedby=-1)
  2774. {
  2775. global $strApproved, $strApprovedFree, $strRequested, $strNotRequested, $strDenied;
  2776. global $strArchivedDenied, $strArchivedNotRequested, $strArchivedRequested;
  2777. global $strArchivedApproved, $strArchivedApprovedFree, $strApprovalStatusUnknown;
  2778. // We add 10 to normal status when we archive holiday
  2779. switch ($approvedid)
  2780. {
  2781. case -2: $status = $strNotRequested; break;
  2782. case -1: $status = $strDenied; break;
  2783. case 0:
  2784. if ($approvedby == 0) $status = $strNotRequested;
  2785. else $status = $strRequested;
  2786. break;
  2787. case 1: $status = $strApproved; break;
  2788. case 2: $status = $strApprovedFree; break;
  2789. case 8: $status = $strArchivedNotRequested; break;
  2790. case 9: $status = $strArchivedDenied; break;
  2791. case 10: $status = $strArchivedRequested; break;
  2792. case 11: $status = $strArchivedApproved; break;
  2793. case 12: $status = $strArchivedApprovedFree; break;
  2794. default: $status = $strApprovalStatusUnknown; break;
  2795. }
  2796. return $status;
  2797. }
  2798. function holidaytype_drop_down($name, $id)
  2799. {
  2800. $holidaytype[HOL_HOLIDAY] = $GLOBALS['strHoliday'];
  2801. $holidaytype[HOL_SICKNESS] = $GLOBALS['strAbsentSick'];
  2802. $holidaytype[HOL_WORKING_AWAY] = $GLOBALS['strWorkingAway'];
  2803. $holidaytype[HOL_TRAINING] = $GLOBALS['strTraining'];
  2804. $holidaytype[HOL_FREE] = $GLOBALS['strCompassionateLeave'];
  2805. $html = "<select name='$name'>";
  2806. if ($id == 0)
  2807. {
  2808. $html .= "<option selected value='0'></option>\n";
  2809. }
  2810. foreach ($holidaytype AS $htypeid => $htype)
  2811. {
  2812. $html .= "<option";
  2813. if ($htypeid == $id)
  2814. {
  2815. $html .= " selected='selected'";
  2816. }
  2817. $html .= " value='{$htypeid}'>{$htype}</option>\n";
  2818. }
  2819. $html .= "</select>\n";
  2820. return $html;
  2821. }
  2822. /**
  2823. * check to see if any fellow group members have holiday on the date specified
  2824. * @author Ivan Lucas
  2825. * @param int $userid - user ID
  2826. * @param int $date - UNIX Timestamp
  2827. * @param string $length - 'day', 'pm' or 'am'
  2828. * @return HTML space seperated list of users that are away on the date specified
  2829. */
  2830. function check_group_holiday($userid, $date, $length='day')
  2831. {
  2832. global $dbUsers, $dbHolidays;
  2833. $namelist = '';
  2834. $groupid = user_group_id($userid);
  2835. if (!empty($groupid))
  2836. {
  2837. // list group members
  2838. $msql = "SELECT id AS userid FROM `{$dbUsers}` ";
  2839. $msql .= "WHERE groupid='{$groupid}' AND id != '$userid' ";
  2840. $mresult = mysql_query($msql);
  2841. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  2842. while ($member = mysql_fetch_object($mresult))
  2843. {
  2844. // check to see if this group member has holiday
  2845. $hsql = "SELECT id FROM `{$dbHolidays}` WHERE userid='{$member->userid}' AND date = FROM_UNIXTIME({$date}) ";
  2846. if ($length == 'am' || $length == 'pm')
  2847. {
  2848. $hsql .= "AND (length = '$length' OR length = 'day') ";
  2849. }
  2850. $hresult = mysql_query($hsql);
  2851. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  2852. if (mysql_num_rows($hresult) >= 1)
  2853. {
  2854. $namelist .= user_realname($member->userid)." ($length)";
  2855. $namelist .= "&nbsp;&nbsp;";
  2856. }
  2857. }
  2858. }
  2859. return $namelist;
  2860. }
  2861. /**
  2862. * Print a listbox of countries
  2863. * @author Ivan Lucas
  2864. * @param string $name - HTML select 'name' attribute
  2865. * @param string $country - Country to pre-select (default to config file setting)
  2866. * @param string $extraattributes - Extra attributes to put on the select tag
  2867. * @return HTML
  2868. * @note if the $country given is not in the list, an editable input box is given instead of a select box
  2869. * @todo TODO i18n country list (How do we do this?)
  2870. */
  2871. function country_drop_down($name, $country, $extraattributes='')
  2872. {
  2873. global $CONFIG;
  2874. if ($country == '') $country = $CONFIG['home_country'];
  2875. if ($country == 'UK') $country = 'UNITED KINGDOM';
  2876. $countrylist[] = 'ALBANIA';
  2877. $countrylist[] = 'ALGERIA';
  2878. $countrylist[] = 'AMERICAN SAMOA';
  2879. $countrylist[] = 'ANDORRA';
  2880. $countrylist[] = 'ANGOLA';
  2881. $countrylist[] = 'ANGUILLA';
  2882. $countrylist[] = 'ANTIGUA';
  2883. $countrylist[] = 'ARGENTINA';
  2884. $countrylist[] = 'ARMENIA';
  2885. $countrylist[] = 'ARUBA';
  2886. $countrylist[] = 'AUSTRALIA';
  2887. $countrylist[] = 'AUSTRIA';
  2888. $countrylist[] = 'AZERBAIJAN';
  2889. $countrylist[] = 'BAHAMAS';
  2890. $countrylist[] = 'BAHRAIN';
  2891. $countrylist[] = 'BANGLADESH';
  2892. $countrylist[] = 'BARBADOS';
  2893. $countrylist[] = 'BELARUS';
  2894. $countrylist[] = 'BELGIUM';
  2895. $countrylist[] = 'BELIZE';
  2896. $countrylist[] = 'BENIN';
  2897. $countrylist[] = 'BERMUDA';
  2898. $countrylist[] = 'BHUTAN';
  2899. $countrylist[] = 'BOLIVIA';
  2900. $countrylist[] = 'BONAIRE';
  2901. $countrylist[] = 'BOSNIA HERZEGOVINA';
  2902. $countrylist[] = 'BOTSWANA';
  2903. $countrylist[] = 'BRAZIL';
  2904. $countrylist[] = 'BRUNEI';
  2905. $countrylist[] = 'BULGARIA';
  2906. $countrylist[] = 'BURKINA FASO';
  2907. $countrylist[] = 'BURUNDI';
  2908. $countrylist[] = 'CAMBODIA';
  2909. $countrylist[] = 'CAMEROON';
  2910. $countrylist[] = 'CANADA';
  2911. $countrylist[] = 'CANARY ISLANDS';
  2912. $countrylist[] = 'CAPE VERDE ISLANDS';
  2913. $countrylist[] = 'CAYMAN ISLANDS';
  2914. $countrylist[] = 'CENTRAL AFRICAN REPUBLIC';
  2915. $countrylist[] = 'CHAD';
  2916. $countrylist[] = 'CHANNEL ISLANDS';
  2917. $countrylist[] = 'CHILE';
  2918. $countrylist[] = 'CHINA';
  2919. $countrylist[] = 'COLOMBIA';
  2920. $countrylist[] = 'COMOROS ISLANDS';
  2921. $countrylist[] = 'CONGO';
  2922. $countrylist[] = 'COOK ISLANDS';
  2923. $countrylist[] = 'COSTA RICA';
  2924. $countrylist[] = 'CROATIA';
  2925. $countrylist[] = 'CUBA';
  2926. $countrylist[] = 'CURACAO';
  2927. $countrylist[] = 'CYPRUS';
  2928. $countrylist[] = 'CZECH REPUBLIC';
  2929. $countrylist[] = 'DENMARK';
  2930. $countrylist[] = 'DJIBOUTI';
  2931. $countrylist[] = 'DOMINICA';
  2932. $countrylist[] = 'DOMINICAN REPUBLIC';
  2933. $countrylist[] = 'ECUADOR';
  2934. $countrylist[] = 'EGYPT';
  2935. $countrylist[] = 'EL SALVADOR';
  2936. $countrylist[] = 'EQUATORIAL GUINEA';
  2937. $countrylist[] = 'ERITREA';
  2938. $countrylist[] = 'ESTONIA';
  2939. $countrylist[] = 'ETHIOPIA';
  2940. $countrylist[] = 'FAROE ISLANDS';
  2941. $countrylist[] = 'FIJI ISLANDS';
  2942. $countrylist[] = 'FINLAND';
  2943. $countrylist[] = 'FRANCE';
  2944. $countrylist[] = 'FRENCH GUINEA';
  2945. $countrylist[] = 'GABON';
  2946. $countrylist[] = 'GAMBIA';
  2947. $countrylist[] = 'GEORGIA';
  2948. $countrylist[] = 'GERMANY';
  2949. $countrylist[] = 'GHANA';
  2950. $countrylist[] = 'GIBRALTAR';
  2951. $countrylist[] = 'GREECE';
  2952. $countrylist[] = 'GREENLAND';
  2953. $countrylist[] = 'GRENADA';
  2954. $countrylist[] = 'GUADELOUPE';
  2955. $countrylist[] = 'GUAM';
  2956. $countrylist[] = 'GUATEMALA';
  2957. $countrylist[] = 'GUINEA REPUBLIC';
  2958. $countrylist[] = 'GUINEA-BISSAU';
  2959. $countrylist[] = 'GUYANA';
  2960. $countrylist[] = 'HAITI';
  2961. $countrylist[] = 'HONDURAS REPUBLIC';
  2962. $countrylist[] = 'HONG KONG';
  2963. $countrylist[] = 'HUNGARY';
  2964. $countrylist[] = 'ICELAND';
  2965. $countrylist[] = 'INDIA';
  2966. $countrylist[] = 'INDONESIA';
  2967. $countrylist[] = 'IRAN';
  2968. $countrylist[] = 'IRELAND, REPUBLIC';
  2969. $countrylist[] = 'ISRAEL';
  2970. $countrylist[] = 'ITALY';
  2971. $countrylist[] = 'IVORY COAST';
  2972. $countrylist[] = 'JAMAICA';
  2973. $countrylist[] = 'JAPAN';
  2974. $countrylist[] = 'JORDAN';
  2975. $countrylist[] = 'KAZAKHSTAN';
  2976. $countrylist[] = 'KENYA';
  2977. $countrylist[] = 'KIRIBATI, REP OF';
  2978. $countrylist[] = 'KOREA, SOUTH';
  2979. $countrylist[] = 'KUWAIT';
  2980. $countrylist[] = 'KYRGYZSTAN';
  2981. $countrylist[] = 'LAOS';
  2982. $countrylist[] = 'LATVIA';
  2983. $countrylist[] = 'LEBANON';
  2984. $countrylist[] = 'LESOTHO';
  2985. $countrylist[] = 'LIBERIA';
  2986. $countrylist[] = 'LIBYA';
  2987. $countrylist[] = 'LIECHTENSTEIN';
  2988. $countrylist[] = 'LITHUANIA';
  2989. $countrylist[] = 'LUXEMBOURG';
  2990. $countrylist[] = 'MACAU';
  2991. $countrylist[] = 'MACEDONIA';
  2992. $countrylist[] = 'MADAGASCAR';
  2993. $countrylist[] = 'MALAWI';
  2994. $countrylist[] = 'MALAYSIA';
  2995. $countrylist[] = 'MALDIVES';
  2996. $countrylist[] = 'MALI';
  2997. $countrylist[] = 'MALTA';
  2998. $countrylist[] = 'MARSHALL ISLANDS';
  2999. $countrylist[] = 'MARTINIQUE';
  3000. $countrylist[] = 'MAURITANIA';
  3001. $countrylist[] = 'MAURITIUS';
  3002. $countrylist[] = 'MEXICO';
  3003. $countrylist[] = 'MOLDOVA, REP OF';
  3004. $countrylist[] = 'MONACO';
  3005. $countrylist[] = 'MONGOLIA';
  3006. $countrylist[] = 'MONTSERRAT';
  3007. $countrylist[] = 'MOROCCO';
  3008. $countrylist[] = 'MOZAMBIQUE';
  3009. $countrylist[] = 'MYANMAR';
  3010. $countrylist[] = 'NAMIBIA';
  3011. $countrylist[] = 'NAURU, REP OF';
  3012. $countrylist[] = 'NEPAL';
  3013. $countrylist[] = 'NETHERLANDS';
  3014. $countrylist[] = 'NEVIS';
  3015. $countrylist[] = 'NEW CALEDONIA';
  3016. $countrylist[] = 'NEW ZEALAND';
  3017. $countrylist[] = 'NICARAGUA';
  3018. $countrylist[] = 'NIGER';
  3019. $countrylist[] = 'NIGERIA';
  3020. $countrylist[] = 'NIUE';
  3021. $countrylist[] = 'NORWAY';
  3022. $countrylist[] = 'OMAN';
  3023. $countrylist[] = 'PAKISTAN';
  3024. $countrylist[] = 'PANAMA';
  3025. $countrylist[] = 'PAPUA NEW GUINEA';
  3026. $countrylist[] = 'PARAGUAY';
  3027. $countrylist[] = 'PERU';
  3028. $countrylist[] = 'PHILLIPINES';
  3029. $countrylist[] = 'POLAND';
  3030. $countrylist[] = 'PORTUGAL';
  3031. $countrylist[] = 'PUERTO RICO';
  3032. $countrylist[] = 'QATAR';
  3033. $countrylist[] = 'REUNION ISLAND';
  3034. $countrylist[] = 'ROMANIA';
  3035. $countrylist[] = 'RUSSIAN FEDERATION';
  3036. $countrylist[] = 'RWANDA';
  3037. $countrylist[] = 'SAIPAN';
  3038. $countrylist[] = 'SAO TOME & PRINCIPE';
  3039. $countrylist[] = 'SAUDI ARABIA';
  3040. $countrylist[] = 'SENEGAL';
  3041. $countrylist[] = 'SEYCHELLES';
  3042. $countrylist[] = 'SIERRA LEONE';
  3043. $countrylist[] = 'SINGAPORE';
  3044. $countrylist[] = 'SLOVAKIA';
  3045. $countrylist[] = 'SLOVENIA';
  3046. $countrylist[] = 'SOLOMON ISLANDS';
  3047. $countrylist[] = 'SOUTH AFRICA';
  3048. $countrylist[] = 'SPAIN';
  3049. $countrylist[] = 'SRI LANKA';
  3050. $countrylist[] = 'ST BARTHELEMY';
  3051. $countrylist[] = 'ST EUSTATIUS';
  3052. $countrylist[] = 'ST KITTS';
  3053. $countrylist[] = 'ST LUCIA';
  3054. $countrylist[] = 'ST MAARTEN';
  3055. $countrylist[] = 'ST VINCENT';
  3056. $countrylist[] = 'SUDAN';
  3057. $countrylist[] = 'SURINAME';
  3058. $countrylist[] = 'SWAZILAND';
  3059. $countrylist[] = 'SWEDEN';
  3060. $countrylist[] = 'SWITZERLAND';
  3061. $countrylist[] = 'SYRIA';
  3062. $countrylist[] = 'TAHITI';
  3063. $countrylist[] = 'TAIWAN';
  3064. $countrylist[] = 'TAJIKISTAN';
  3065. $countrylist[] = 'TANZANIA';
  3066. $countrylist[] = 'THAILAND';
  3067. $countrylist[] = 'TOGO';
  3068. $countrylist[] = 'TONGA';
  3069. $countrylist[] = 'TRINIDAD & TOBAGO';
  3070. $countrylist[] = 'TURKEY';
  3071. $countrylist[] = 'TURKMENISTAN';
  3072. $countrylist[] = 'TURKS & CAICOS ISLANDS';
  3073. $countrylist[] = 'TUVALU';
  3074. $countrylist[] = 'UGANDA';
  3075. // $countrylist[] = 'UK';
  3076. $countrylist[] = 'UKRAINE';
  3077. $countrylist[] = 'UNITED KINGDOM';
  3078. $countrylist[] = 'UNITED STATES';
  3079. $countrylist[] = 'URUGUAY';
  3080. $countrylist[] = 'UTD ARAB EMIRATES';
  3081. $countrylist[] = 'UZBEKISTAN';
  3082. $countrylist[] = 'VANUATU';
  3083. $countrylist[] = 'VENEZUELA';
  3084. $countrylist[] = 'VIETNAM';
  3085. $countrylist[] = 'VIRGIN ISLANDS';
  3086. $countrylist[] = 'VIRGIN ISLANDS (UK)';
  3087. $countrylist[] = 'WESTERN SAMOA';
  3088. $countrylist[] = 'YEMAN, REP OF';
  3089. $countrylist[] = 'YUGOSLAVIA';
  3090. $countrylist[] = 'ZAIRE';
  3091. $countrylist[] = 'ZAMBIA';
  3092. $countrylist[] = 'ZIMBABWE';
  3093. if (in_array(strtoupper($country), $countrylist))
  3094. {
  3095. // make drop down
  3096. $html = "<select id=\"{$name}\" name=\"{$name}\" {$extraattributes}>";
  3097. foreach ($countrylist as $key => $value)
  3098. {
  3099. $value = htmlspecialchars($value);
  3100. $html .= "<option value='$value'";
  3101. if ($value == strtoupper($country))
  3102. {
  3103. $html .= " selected='selected'";
  3104. }
  3105. $html .= ">$value</option>\n";
  3106. }
  3107. $html .= "</select>";
  3108. }
  3109. else
  3110. {
  3111. // make editable input box
  3112. $html = "<input maxlength='100' name='{$name}' size='40' value='{$country}' {$extraattributes} />";
  3113. }
  3114. return $html;
  3115. }
  3116. function check_email($email, $check_dns = FALSE)
  3117. {
  3118. if ((preg_match('/(@.*@)|(\.\.)|(@\.)|(\.@)|(^\.)/', $email)) ||
  3119. (preg_match('/^.+\@(\[?)[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,3}|[0-9]{1,3})(\]?)$/',$email)))
  3120. {
  3121. if ($check_dns)
  3122. {
  3123. $host = explode('@', $email);
  3124. // Check for MX record
  3125. if ( checkdnsrr($host[1], 'MX') ) return TRUE;
  3126. // Check for A record
  3127. if ( checkdnsrr($host[1], 'A') ) return TRUE;
  3128. // Check for CNAME record
  3129. if ( checkdnsrr($host[1], 'CNAME') ) return TRUE;
  3130. }
  3131. else
  3132. {
  3133. return TRUE;
  3134. }
  3135. }
  3136. return FALSE;
  3137. }
  3138. function incident_get_next_target($incidentid)
  3139. {
  3140. global $now;
  3141. // Find the most recent SLA target that was met
  3142. $sql = "SELECT sla,timestamp FROM `{$GLOBALS['dbUpdates']}` WHERE incidentid='{$incidentid}' AND type='slamet' ORDER BY id DESC LIMIT 1";
  3143. $result = mysql_query($sql);
  3144. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  3145. $target = '';
  3146. if (mysql_num_rows($result) > 0)
  3147. {
  3148. $upd = mysql_fetch_object($result);
  3149. switch ($upd->sla)
  3150. {
  3151. case 'opened': $target->type = 'initialresponse'; break;
  3152. case 'initialresponse': $target->type = 'probdef'; break;
  3153. case 'probdef': $target->type = 'actionplan'; break;
  3154. case 'actionplan': $target->type = 'solution'; break;
  3155. case 'solution': $target->type=''; break;
  3156. //case 'solution': $target->type = 'probdef'; break;
  3157. case 'closed': $target->type = 'opened'; break;
  3158. }
  3159. $target->since = calculate_incident_working_time($incidentid,$upd->timestamp,$now);
  3160. }
  3161. else
  3162. {
  3163. $target->type = 'regularcontact';
  3164. $target->since = 0;
  3165. }
  3166. return $target;
  3167. }
  3168. function target_type_name($targettype)
  3169. {
  3170. switch ($targettype)
  3171. {
  3172. case 'opened': $name = $GLOBALS['strOpened']; break;
  3173. case 'initialresponse': $name = $GLOBALS['strInitialResponse']; break;
  3174. case 'probdef': $name = $GLOBALS['strProblemDefinition']; break;
  3175. case 'actionplan': $name = $GLOBALS['strActionPlan']; break;
  3176. case 'solution': $name = $GLOBALS['strResolutionReprioritisation']; break;
  3177. case 'closed': $name=''; break;
  3178. case 'regularcontact': $name=''; break; // Contact Customer
  3179. default: $name=''; break;
  3180. }
  3181. return $name;
  3182. }
  3183. function incident_get_next_review($incidentid)
  3184. {
  3185. global $now;
  3186. $sql = "SELECT timestamp FROM `{$GLOBALS['dbUpdates']}` WHERE incidentid='{$incidentid}' AND type='reviewmet' ORDER BY id DESC LIMIT 1";
  3187. $result = mysql_query($sql);
  3188. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  3189. if (mysql_num_rows($result) > 0)
  3190. {
  3191. $upd = mysql_fetch_object($result);
  3192. $timesincereview = floor(($now - ($upd->timestamp)) / 60);
  3193. }
  3194. return $timesincereview;
  3195. }
  3196. /**
  3197. * Converts a MySQL date to a UNIX Timestamp
  3198. * @author Ivan Lucas
  3199. * @param string $mysqldate - A date column from mysql
  3200. * @param bool $utc - TRUE = Timestamp given is UTC
  3201. * FALSE = Timestamp as system time
  3202. * @returns integer. a UNIX Timestamp
  3203. */
  3204. function mysql2date($mysqldate, $utc = FALSE)
  3205. {
  3206. // for the zero/blank case, return 0
  3207. if (empty($mysqldate))
  3208. {
  3209. return 0;
  3210. }
  3211. if ($mysqldate == '0000-00-00 00:00:00' OR $mysqldate == '0000-00-00')
  3212. {
  3213. return 0;
  3214. }
  3215. // Takes a MYSQL date and converts it to a proper PHP date
  3216. $day = substr($mysqldate,8,2);
  3217. $month = substr($mysqldate,5,2);
  3218. $year = substr($mysqldate,0,4);
  3219. if (strlen($mysqldate) > 10)
  3220. {
  3221. $hour = substr($mysqldate,11,2);
  3222. $minute = substr($mysqldate,14,2);
  3223. $second = substr($mysqldate,17,2);
  3224. if ($utc) $phpdate = gmmktime($hour,$minute,$second,$month,$day,$year);
  3225. else $phpdate = mktime($hour,$minute,$second,$month,$day,$year);
  3226. }
  3227. else
  3228. {
  3229. if ($utc) $phpdate = gmmktime(0, 0, 0, $month, $day, $year);
  3230. else $phpdate = mktime(0, 0, 0, $month, $day, $year);
  3231. }
  3232. return $phpdate;
  3233. }
  3234. /**
  3235. * Converts a MySQL timestamp to a UNIX Timestamp
  3236. * @author Ivan Lucas
  3237. * @param string $mysqldate A timestamp column from mysql
  3238. * @returns integer. a UNIX Timestamp
  3239. */
  3240. function mysqlts2date($mysqldate)
  3241. {
  3242. // for the zero/blank case, return 0
  3243. if (empty($mysqldate)) return 0;
  3244. // Takes a MYSQL date and converts it to a proper PHP date
  3245. if (strlen($mysqldate) == 14)
  3246. {
  3247. $day = substr($mysqldate,6,2);
  3248. $month = substr($mysqldate,4,2);
  3249. $year = substr($mysqldate,0,4);
  3250. $hour = substr($mysqldate,8,2);
  3251. $minute = substr($mysqldate,10,2);
  3252. $second = substr($mysqldate,12,2);
  3253. }
  3254. elseif (strlen($mysqldate) > 14)
  3255. {
  3256. $day = substr($mysqldate,8,2);
  3257. $month = substr($mysqldate,5,2);
  3258. $year = substr($mysqldate,0,4);
  3259. $hour = substr($mysqldate,11,2);
  3260. $minute = substr($mysqldate,14,2);
  3261. $second = substr($mysqldate,17,2);
  3262. }
  3263. $phpdate = mktime($hour,$minute,$second,$month,$day,$year);
  3264. return $phpdate;
  3265. }
  3266. function iso_8601_date($timestamp)
  3267. {
  3268. $date_mod = date('Y-m-d\TH:i:s', $timestamp);
  3269. $pre_timezone = date('O', $timestamp);
  3270. $time_zone = substr($pre_timezone, 0, 3).":".substr($pre_timezone, 3, 2);
  3271. $date_mod .= $time_zone;
  3272. return $date_mod;
  3273. }
  3274. /**
  3275. * Decide whether the time is during a public holiday
  3276. * @author Paul Heaney
  3277. * @param int $time Timestamp to identify
  3278. * @param array $publicholidays array of Holiday. Public holiday to compare against
  3279. * @returns integer. If > 0 number of seconds left in the public holiday
  3280. */
  3281. function is_public_holiday($time, $publicholidays)
  3282. {
  3283. if (!empty($publicholidays))
  3284. {
  3285. foreach ($publicholidays AS $holiday)
  3286. {
  3287. if ($time >= $holiday->starttime AND $time <= $holiday->endtime)
  3288. {
  3289. return $holiday->endtime-$time;
  3290. }
  3291. }
  3292. }
  3293. return 0;
  3294. }
  3295. /**
  3296. * Calculate the working time between two timestamps
  3297. * @author Tom Gerrard, Ivan Lucas, Paul Heaney
  3298. * @param int $t1. The start timestamp (earliest date/time)
  3299. * @param int $t2. The ending timetamp (latest date/time)
  3300. * @returns integer. the number of working minutes (minutes in the working day)
  3301. */
  3302. function calculate_working_time($t1, $t2, $publicholidays)
  3303. {
  3304. // PH 16/12/07 Old function commented out, rewritten to support public holidays. Old code to be removed once we're happy this is stable
  3305. // KH 13/07/08 Use old function again for 3.35 beta
  3306. // Note that this won't work if we have something
  3307. // more complicated than a weekend
  3308. global $CONFIG;
  3309. $swd = $CONFIG['start_working_day'] / 3600;
  3310. $ewd = $CONFIG['end_working_day'] / 3600;
  3311. // Just in case the time params are the wrong way around ...
  3312. if ( $t1 > $t2 )
  3313. {
  3314. $t3 = $t2;
  3315. $t2 = $t1;
  3316. $t1 = $t3;
  3317. }
  3318. // We don't need all the elements here. hours, days and year are used
  3319. // later on to calculate the difference. wday is just used in this
  3320. // section
  3321. $at1 = getdate($t1);
  3322. $at2 = getdate($t2);
  3323. // Make sure that the start time is on a valid day and within normal hours
  3324. // if it isn't then move it forward to the next work minute
  3325. if ($at1['hours'] > $ewd)
  3326. {
  3327. do
  3328. {
  3329. $at1['yday'] ++;
  3330. $at1['wday'] ++;
  3331. $at1['wday'] %= 7;
  3332. if ($at1['yday'] > 365)
  3333. {
  3334. $at1['year'] ++;
  3335. $at1['yday'] = 0;
  3336. }
  3337. } while (!in_array($at1['wday'],$CONFIG['working_days']));
  3338. $at1['hours']=$swd;
  3339. $at1['minutes']=0;
  3340. }
  3341. else
  3342. {
  3343. if (($at1['hours']<$swd) || (!in_array($at1['wday'],$CONFIG['working_days'])))
  3344. {
  3345. while (!in_array($at1['wday'], $CONFIG['working_days']))
  3346. {
  3347. $at1['yday'] ++;
  3348. $at1['wday'] ++;
  3349. $at1['wday'] %= 7;
  3350. if ($at1['days']>365)
  3351. {
  3352. $at1['year'] ++;
  3353. $at1['yday'] = 0;
  3354. }
  3355. }
  3356. $at1['hours'] = $swd;
  3357. $at1['minutes'] = 0;
  3358. }
  3359. }
  3360. // Same again but for the end time
  3361. // if it isn't then move it backward to the previous work minute
  3362. if ( $at2['hours']<$swd)
  3363. {
  3364. do
  3365. {
  3366. $at2['yday'] --;
  3367. $at2['wday'] --;
  3368. if ($at2['wday'] < 0) $at2['wday'] = 6;
  3369. if ($at2['yday'] < 0)
  3370. {
  3371. $at2['yday'] = 365;
  3372. $at2['year'] --;
  3373. }
  3374. } while (!in_array($at2['wday'], $CONFIG['working_days']));
  3375. $at2['hours'] = $ewd;
  3376. $at2['minutes'] = 0;
  3377. }
  3378. else
  3379. {
  3380. if (($at2['hours']>$ewd) || (!in_array($at2['wday'],$CONFIG['working_days'])))
  3381. {
  3382. while (!in_array($at2['wday'],$CONFIG['working_days']))
  3383. {
  3384. $at2['yday'] --;
  3385. $at2['wday'] --;
  3386. if ($at2['wday'] < 0) $at2['wday'] = 6;
  3387. if ($at2['yday'] < 0)
  3388. {
  3389. $at2['yday'] = 365;
  3390. $at2['year'] --;
  3391. }
  3392. }
  3393. $at2['hours'] = $ewd;
  3394. $at2['minutes'] = 0;
  3395. }
  3396. }
  3397. $t1 = mktime($at1['hours'], $at1['minutes'], 0, 1, $at1['yday'] + 1, $at1['year']);
  3398. $t2 = mktime($at2['hours'], $at2['minutes'], 0, 1, $at2['yday'] + 1, $at2['year']);
  3399. $weeks = floor(($t2 - $t1) / (60 * 60 * 24 * 7));
  3400. $t1 += $weeks * 60 * 60 * 24 * 7;
  3401. while ( date('z',$t2) != date('z',$t1) )
  3402. {
  3403. if (in_array(date('w',$t1),$CONFIG['working_days'])) $days++;
  3404. $t1 += (60 * 60 * 24);
  3405. }
  3406. // this could be negative and that's not ok
  3407. $coefficient = 1;
  3408. if ($t2 < $t1)
  3409. {
  3410. $t3 = $t2;
  3411. $t2 = $t1;
  3412. $t1 = $t3;
  3413. $coefficient =- 1;
  3414. }
  3415. $min = floor( ($t2 - $t1) / 60 ) * $coefficient;
  3416. $minutes= $min + ($weeks * count($CONFIG['working_days']) + $days ) * ($ewd-$swd) * 60;
  3417. return $minutes;
  3418. //new version below
  3419. /*
  3420. global $CONFIG;
  3421. $swd = $CONFIG['start_working_day']/3600;
  3422. $ewd = $CONFIG['end_working_day']/3600;
  3423. // Just in case they are the wrong way around ...
  3424. if ( $t1 > $t2 )
  3425. {
  3426. $t3 = $t2;
  3427. $t2 = $t1;
  3428. $t1 = $t3;
  3429. }
  3430. $currenttime = $t1;
  3431. $timeworked = 0;
  3432. $t2date = getdate($t2);
  3433. $midnight = 1440; // 24 * 60 minutes
  3434. while ($currenttime < $t2) // was <=
  3435. {
  3436. $time = getdate($currenttime);
  3437. $ph = 0;
  3438. if (in_array($time['wday'], $CONFIG['working_days']) AND $time['hours'] >= $swd
  3439. AND $time['hours'] <= $ewd AND (($ph = is_public_holiday($currenttime, $publicholidays)) == 0))
  3440. {
  3441. if ($t2date['yday'] == $time['yday'] AND $t2date['year'] == $time['year'])
  3442. {
  3443. // if end same day as time
  3444. $c = $t2 - $currenttime;
  3445. $timeworked += $c/60;
  3446. $currenttime += $c;
  3447. }
  3448. else
  3449. {
  3450. // End on a different day
  3451. $secondsintoday = (($t2date['hours']*60)*60)+($t2date['minutes']*60)+$t2date['seconds'];
  3452. $timeworked += ($CONFIG['end_working_day']-$secondsintoday)/60;
  3453. $currenttime += ($midnight*$secondsintoday)+$swd;
  3454. }
  3455. }
  3456. else
  3457. {
  3458. // Jump closer to the next work minute
  3459. if (!in_array($time['wday'], $CONFIG['working_days']))
  3460. {
  3461. // Move to next day
  3462. $c = ($time['hours'] * 60) + $time['minutes'];
  3463. $diff = $midnight - $c;
  3464. $currenttime += ($diff * 60); // to seconds
  3465. // Jump to start of working day
  3466. $currenttime += ($swd * 60);
  3467. }
  3468. else if ($time['hours'] < $swd)
  3469. {
  3470. // jump to beginning of working day
  3471. $c = ($time['hours'] * 60) + $time['minutes'];
  3472. $diff = ($swd * 60) - $c;
  3473. $currenttime += ($diff * 60); // to seconds
  3474. }
  3475. else if ($time['hours'] > $ewd)
  3476. {
  3477. // Jump to the start of the next working day
  3478. $c = ($midnight - (($time['hours'] * 60) + $time['minutes'])) + ($swd * 60);
  3479. $currenttime += ($c * 60);
  3480. }
  3481. else if ($ph != 0)
  3482. {
  3483. // jump to the minute after the public holiday
  3484. $currenttime += $ph + 60;
  3485. // Jump to start of working day
  3486. $currenttime += ($swd * 60);
  3487. }
  3488. else
  3489. {
  3490. $currenttime += 60; // move to the next minute
  3491. }
  3492. }
  3493. }
  3494. return $timeworked;
  3495. */
  3496. }
  3497. /**
  3498. * @author Ivan Lucas
  3499. */
  3500. function is_active_status($status, $states)
  3501. {
  3502. if (in_array($status, $states)) return false;
  3503. else return true;
  3504. }
  3505. /**
  3506. * Function to get an array of public holidays
  3507. * @author Paul Heaney
  3508. * @param int $startdate - UNIX Timestamp of start of the period to find public holidays in
  3509. * @param int $enddate - UNIX Timestamp of end of the period to find public holidays in
  3510. * @return array of Holiday
  3511. */
  3512. function get_public_holidays($startdate, $enddate)
  3513. {
  3514. $sql = "SELECT * FROM `{$GLOBALS['dbHolidays']}` ";
  3515. $sql .= "WHERE type = ".HOL_PUBLIC." AND (`date` >= FROM_UNIXTIME({$startdate}) AND `date` <= FROM_UNIXTIME({$enddate}))";
  3516. $result = mysql_query($sql);
  3517. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  3518. $publicholidays = array();
  3519. if (mysql_num_rows($result) > 0)
  3520. {
  3521. // Assume public holidays are ALL day
  3522. while ($obj = mysql_fetch_object($result))
  3523. {
  3524. $holiday = new Holiday();
  3525. $holiday->starttime = $obj->date;
  3526. $holiday->endtime = ($obj->date+(60*60*24));
  3527. $publicholidays[] = $holiday;
  3528. }
  3529. }
  3530. return $publicholidays;
  3531. }
  3532. /**
  3533. * Calculate the engineer working time between two timestamps for a given incident
  3534. i.e. ignore times when customer has action
  3535. * @author Ivan Lucas
  3536. @param int $incidentid - The incident ID to perform a calculation on
  3537. @param int $t1 - UNIX Timestamp. Start of range
  3538. @param int $t2 - UNIX Timestamp. End of range
  3539. @param array $states (optional) Does not count time when the incident is set to
  3540. any of the states in this array. (Default is closed, awaiting closure and awaiting customer action)
  3541. */
  3542. function calculate_incident_working_time($incidentid, $t1, $t2, $states=array(2,7,8))
  3543. {
  3544. if ( $t1 > $t2 )
  3545. {
  3546. $t3 = $t2;
  3547. $t2 = $t1;
  3548. $t1 = $t3;
  3549. }
  3550. $startofday = mktime(0,0,0, date("m",$t1), date("d",$t1), date("Y",$t1));
  3551. $endofday = mktime(23,59,59, date("m",$t2), date("d",$t2), date("Y",$t2));
  3552. $publicholidays = get_public_holidays($startofday, $endofday);
  3553. $sql = "SELECT id, currentstatus, timestamp FROM `{$GLOBALS['dbUpdates']}` WHERE incidentid='{$incidentid}' ORDER BY id ASC";
  3554. $result = mysql_query($sql);
  3555. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  3556. $time = 0;
  3557. $timeptr = 0;
  3558. $laststatus = 2; // closed
  3559. while ($update = mysql_fetch_array($result))
  3560. {
  3561. // if ($t1<=$update['timestamp'])
  3562. if ($t1 <= $update['timestamp'])
  3563. {
  3564. if ($timeptr == 0)
  3565. {
  3566. // This is the first update
  3567. // If it's active, set the ptr = t1
  3568. // otherwise set to current timestamp ???
  3569. if (is_active_status($laststatus, $states))
  3570. {
  3571. $timeptr = $t1;
  3572. }
  3573. else
  3574. {
  3575. $timeptr = $update['timestamp'];
  3576. }
  3577. }
  3578. if ($t2 < $update['timestamp'])
  3579. {
  3580. // If we have reached the very end of the range, increment time to end of range, break
  3581. if (is_active_status($laststatus, $states))
  3582. {
  3583. $time += calculate_working_time($timeptr,$t2,$publicholidays);
  3584. }
  3585. break;
  3586. }
  3587. // if status has changed or this is the first (active update)
  3588. if (is_active_status($laststatus, $states) != is_active_status($update['currentstatus'], $states))
  3589. {
  3590. // If it's active and we've not reached the end of the range, increment time
  3591. if (is_active_status($laststatus, $states) && ($t2 >= $update['timestamp']))
  3592. {
  3593. $time += calculate_working_time($timeptr,$update['timestamp'], $publicholidays);
  3594. }
  3595. else
  3596. {
  3597. $timeptr = $update['timestamp'];
  3598. }
  3599. // if it's not active set the ptr
  3600. }
  3601. }
  3602. $laststatus = $update['currentstatus'];
  3603. }
  3604. mysql_free_result($result);
  3605. // Calculate remainder
  3606. if (is_active_status($laststatus, $states) && ($t2 >= $update['timestamp']))
  3607. {
  3608. $time += calculate_working_time($timeptr,$t2,$publicholidays);
  3609. }
  3610. return $time;
  3611. }
  3612. /**
  3613. * Takes a UNIX Timestamp and returns a string with a pretty readable date
  3614. * @param int $date
  3615. * @param string $lang. takes either 'user' or 'system' as to which language to use
  3616. * @returns string
  3617. */
  3618. function readable_date($date, $lang = 'user')
  3619. {
  3620. global $SYSLANG;
  3621. //
  3622. // e.g. Yesterday @ 5:28pm
  3623. if (ldate('dmy', $date) == ldate('dmy', time()))
  3624. {
  3625. if ($lang == 'user')
  3626. {
  3627. $datestring = "{$GLOBALS['strToday']} @ ".ldate('g:ia', $date);
  3628. }
  3629. else
  3630. {
  3631. $datestring = "{$SYSLANG['strToday']} @ ".ldate('g:ia', $date);
  3632. }
  3633. }
  3634. elseif (ldate('dmy', $date) == ldate('dmy', (time()-86400)))
  3635. {
  3636. if ($lang == 'user')
  3637. {
  3638. $datestring = "{$GLOBALS['strYesterday']} @ ".ldate('g:ia', $date);
  3639. }
  3640. else
  3641. {
  3642. $datestring = "{$SYSLANG['strYesterday']} @ ".ldate('g:ia', $date);
  3643. }
  3644. }
  3645. else
  3646. {
  3647. $datestring = ldate("l jS M y @ g:ia", $date);
  3648. }
  3649. return $datestring;
  3650. }
  3651. /**
  3652. * Return the email address of the notify contact of the given contact
  3653. * @author Ivan Lucas
  3654. * @returns string. email address.
  3655. */
  3656. function contact_notify_email($contactid)
  3657. {
  3658. global $dbContacts;
  3659. $sql = "SELECT notify_contactid FROM `{$dbContacts}` WHERE id='$contactid' LIMIT 1";
  3660. $result = mysql_query($sql);
  3661. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  3662. list($notify_contactid) = mysql_fetch_row($result);
  3663. $sql = "SELECT email FROM `{$dbContacts}` WHERE id='$notify_contactid' LIMIT 1";
  3664. $result = mysql_query($sql);
  3665. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  3666. list($email) = mysql_fetch_row($result);
  3667. return $email;
  3668. }
  3669. /**
  3670. * Returns the contact ID of the notify contact for the given contact ID
  3671. * @author Ivan Lucas
  3672. * @param int $contactid. Contact ID
  3673. * @param int $level. Number of levels to recurse upwards
  3674. * @note If Level is specified and is >= 1 then the notify contact is
  3675. * found recursively, ie. the notify contact of the notify contact etc.
  3676. */
  3677. function contact_notify($contactid, $level=0)
  3678. {
  3679. global $dbContacts;
  3680. $notify_contactid = 0;
  3681. if ($level == 0)
  3682. {
  3683. return $contactid;
  3684. }
  3685. else
  3686. {
  3687. $sql = "SELECT notify_contactid FROM `{$dbContacts}` WHERE id='$contactid' LIMIT 1";
  3688. $result = mysql_query($sql);
  3689. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  3690. list($notify_contactid) = mysql_fetch_row($result);
  3691. if ($level > 0)
  3692. {
  3693. $newlevel = $level -1;
  3694. $notify_contactid = contact_notify($notify_contactid, $newlevel);
  3695. }
  3696. return $notify_contactid;
  3697. }
  3698. }
  3699. /**
  3700. * HTML select box listing substitute engineers
  3701. * @author Ivan Lucas
  3702. */
  3703. function software_backup_dropdown($name, $userid, $softwareid, $backupid)
  3704. {
  3705. global $dbUsers, $dbUserSoftware, $dbSoftware;
  3706. $sql = "SELECT *, u.id AS userid FROM `{$dbUserSoftware}` AS us, `{$dbSoftware}` AS s, `{$dbUsers}` AS u ";
  3707. $sql .= "WHERE us.softwareid = s.id ";
  3708. $sql .= "AND s.id = '$softwareid' ";
  3709. $sql .= "AND userid != '{$userid}' AND u.status > 0 ";
  3710. $sql .= "AND us.userid = u.id ";
  3711. $sql .= " ORDER BY realname";
  3712. $result = mysql_query($sql);
  3713. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  3714. $countsw = mysql_num_rows($result);
  3715. if ($countsw >= 1)
  3716. {
  3717. $html = "<select name='$name'>\n";
  3718. $html .= "<option value='0'";
  3719. if ($user->userid==0) $html .= " selected='selected'";
  3720. $html .= ">{$GLOBALS['strNone']}</option>\n";
  3721. while ($user = mysql_fetch_object($result))
  3722. {
  3723. $html .= "<option value='{$user->userid}'";
  3724. if ($user->userid == $backupid) $html .= " selected='selected'";
  3725. $html .= ">{$user->realname}</option>\n";
  3726. }
  3727. $html .= "</select>\n";
  3728. }
  3729. else
  3730. {
  3731. $html .= "<input type='hidden' name='$name' value='0' />{$GLOBALS['strNoneAvailable']}";
  3732. }
  3733. return ($html);
  3734. }
  3735. /**
  3736. *
  3737. * @author Ivan Lucas
  3738. */
  3739. function software_backup_userid($userid, $softwareid)
  3740. {
  3741. global $dbUserSoftware;
  3742. $backupid = 0; // default
  3743. // Find out who is the substitute for this user/skill
  3744. $sql = "SELECT backupid FROM `{$dbUserSoftware}` WHERE userid = '$userid' AND softwareid = '$softwareid'";
  3745. $result = mysql_query($sql);
  3746. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  3747. list($backupid) = mysql_fetch_row($result);
  3748. $backup1 = $backupid;
  3749. // If that substitute is not accepting then try and find another
  3750. if (empty($backupid) OR user_accepting($backupid) != 'Yes')
  3751. {
  3752. $sql = "SELECT backupid FROM `{$dbUserSoftware}` WHERE userid='$backupid' AND userid!='$userid' ";
  3753. $sql .= "AND softwareid='$softwareid' AND backupid!='$backup1'";
  3754. $result = mysql_query($sql);
  3755. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  3756. list($backupid) = mysql_fetch_row($result);
  3757. $backup2=$backupid;
  3758. }
  3759. // One more iteration, is the backup of the backup accepting? If not try another
  3760. if (empty($backupid) OR user_accepting($backupid)!='Yes')
  3761. {
  3762. $sql = "SELECT backupid FROM `{$dbUserSoftware}` WHERE userid='$backupid' AND userid!='$userid' ";
  3763. $sql .= "AND softwareid='$softwareid' AND backupid!='$backup1' AND backupid!='$backup2'";
  3764. $result = mysql_query($sql);
  3765. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  3766. list($backupid) = mysql_fetch_row($result);
  3767. }
  3768. return ($backupid);
  3769. }
  3770. /**
  3771. * Switches incidents temporary owners to the backup/substitute engineer depending on the setting of 'accepting'
  3772. * @author Ivan Lucas
  3773. * @param int $userid. The userid of the user who's status has changed.
  3774. * @param string $accepting. 'yes' or 'no' to indicate whether the user is accepting
  3775. * @note if the $accepting parameter is 'no' then the function will attempt to temporarily assign
  3776. * all the open incidents that the user owns to the users defined substitute engineers
  3777. * If Substitute engineers cannot be found or they themselves are not accepting, the given users incidents
  3778. * are placed in the holding queue
  3779. */
  3780. function incident_backup_switchover($userid, $accepting)
  3781. {
  3782. global $now, $dbIncidents, $dbUpdates, $dbTempAssigns, $dbUsers, $dbUserStatus;
  3783. $usersql = "SELECT u.*, us.name AS statusname ";
  3784. $usersql .= "FROM `{$dbUsers}` AS u, `{$dbUserStatus}` AS us ";
  3785. $usersql .= "WHERE u.id = '{$userid}' AND u.status = us.id";
  3786. $userresult = mysql_query($usersql);
  3787. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  3788. $user = mysql_fetch_row($userresult);
  3789. if (strtolower($accepting) == 'no')
  3790. {
  3791. // Look through the incidents that this user OWNS (and are not closed)
  3792. $sql = "SELECT * FROM `{$dbIncidents}` WHERE (owner='$userid' OR towner='$userid') AND status!=2";
  3793. $result = mysql_query($sql);
  3794. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  3795. while ($incident = mysql_fetch_object($result))
  3796. {
  3797. // Try and find a backup/substitute engineer
  3798. $backupid = software_backup_userid($userid, $incident->softwareid);
  3799. if (empty($backupid) OR user_accepting($backupid) == 'No')
  3800. {
  3801. // no backup engineer found so add to the holding queue
  3802. // Look to see if this assignment is in the queue already
  3803. $fsql = "SELECT * FROM `{$dbTempAssigns}` WHERE incidentid='{$incident->id}' AND originalowner='{$userid}'";
  3804. $fresult = mysql_query($fsql);
  3805. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  3806. if (mysql_num_rows($fresult) < 1)
  3807. {
  3808. // it's not in the queue, and the user isn't accepting so add it
  3809. //$userstatus=user_status($userid);
  3810. $userstatus = $user['status'];
  3811. $usql = "INSERT INTO `{$dbTempAssigns}` (incidentid,originalowner,userstatus) VALUES ('{$incident->id}', '{$userid}', '$userstatus')";
  3812. mysql_query($usql);
  3813. if (mysql_error()) trigger_error(mysql_error(),E_USER_ERROR);
  3814. }
  3815. }
  3816. else
  3817. {
  3818. // do an automatic temporary reassign
  3819. // update incident
  3820. $rusql = "UPDATE `{$dbIncidents}` SET ";
  3821. $rusql .= "towner='{$backupid}', lastupdated='$now' WHERE id='{$incident->id}' LIMIT 1";
  3822. mysql_query($rusql);
  3823. if (mysql_error()) trigger_error(mysql_error(),E_USER_ERROR);
  3824. // add update
  3825. $username=user_realname($userid);
  3826. //$userstatus = userstatus_name(user_status($userid));
  3827. $userstatus = $user['statusname'];
  3828. //$usermessage=user_message($userid);
  3829. $usermessage = $user['message'];
  3830. $bodytext = "Previous Incident Owner ({$username}) {$userstatus} {$usermessage}";
  3831. $assigntype = 'tempassigning';
  3832. $risql = "INSERT INTO `{$dbUpdates}` (incidentid, userid, bodytext, type, timestamp, currentowner, currentstatus) ";
  3833. $risql .= "VALUES ('{$incident->id}', '0', '$bodytext', '$assigntype', '$now', ";
  3834. $risql .= "'{$backupid}', ";
  3835. $risql .= "'{$incident->status}')";
  3836. mysql_query($risql);
  3837. if (mysql_error()) trigger_error(mysql_error(),E_USER_ERROR);
  3838. // Look to see if this assignment is in the queue already
  3839. $fsql = "SELECT * FROM `{$dbTempAssigns}` WHERE incidentid='{$incident->id}' AND originalowner='{$userid}'";
  3840. $fresult = mysql_query($fsql);
  3841. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  3842. if (mysql_num_rows($fresult) < 1)
  3843. {
  3844. //$userstatus=user_status($userid);
  3845. $userstatus = $user['status'];
  3846. $usql = "INSERT INTO `{$dbTempAssigns}` (incidentid,originalowner,userstatus,assigned) VALUES ('{$incident->id}', '{$userid}', '$userstatus','yes')";
  3847. mysql_query($usql);
  3848. if (mysql_error()) trigger_error(mysql_error(),E_USER_ERROR);
  3849. }
  3850. else
  3851. {
  3852. // mark the temp assigns table so it's not showing in the holding queue
  3853. $tasql = "UPDATE `{$dbTempAssigns}` SET assigned='yes' WHERE originalowner='$userid' AND incidentid='{$incident->id}' LIMIT 1";
  3854. mysql_query($tasql);
  3855. if (mysql_error()) trigger_error(mysql_error(),E_USER_ERROR);
  3856. }
  3857. }
  3858. }
  3859. }
  3860. elseif ($accepting=='')
  3861. {
  3862. // Do nothing when accepting status doesn't exist
  3863. }
  3864. else
  3865. {
  3866. // The user is now ACCEPTING, so first have a look to see if there are any reassignments in the queue
  3867. $sql = "SELECT * FROM `{$dbTempAssigns}` WHERE originalowner='{$userid}' ";
  3868. $result = mysql_query($sql);
  3869. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  3870. while ($assign = mysql_fetch_object($result))
  3871. {
  3872. if ($assign->assigned == 'yes')
  3873. {
  3874. // Incident has actually been reassigned, so have a look if we can grab it back.
  3875. $lsql = "SELECT id,status FROM `{$dbIncidents}` WHERE id='{$assign->incidentid}' AND owner='{$assign->originalowner}' AND towner!=''";
  3876. $lresult = mysql_query($lsql);
  3877. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  3878. while ($incident = mysql_fetch_object($lresult))
  3879. {
  3880. // Find our tempassign
  3881. $usql = "SELECT id,currentowner FROM `{$dbUpdates}` WHERE incidentid='{$incident->id}' AND userid='0' AND type='tempassigning' ORDER BY id DESC LIMIT 1";
  3882. $uresult = mysql_query($usql);
  3883. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  3884. list($prevassignid,$tempowner) = mysql_fetch_row($uresult);
  3885. // Look to see if the temporary owner has updated the incident since we temp assigned it
  3886. // If he has, we leave it in his queue
  3887. $usql = "SELECT id FROM `{$dbUpdates}` WHERE incidentid='{$incident->id}' AND id > '{$prevassignid}' AND userid='$tempowner' LIMIT 1 ";
  3888. $uresult = mysql_query($usql);
  3889. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  3890. if (mysql_num_rows($uresult) < 1)
  3891. {
  3892. // Incident appears not to have been updated by the temporary owner so automatically reassign back to orignal owner
  3893. // update incident
  3894. $rusql = "UPDATE `{$dbIncidents}` SET ";
  3895. $rusql .= "towner='', lastupdated='$now' WHERE id='{$incident->id}' LIMIT 1";
  3896. mysql_query($rusql);
  3897. if (mysql_error()) trigger_error(mysql_error(),E_USER_ERROR);
  3898. // add update
  3899. $username = user_realname($userid);
  3900. //$userstatus = userstatus_name(user_status($userid));
  3901. $userstatus = $user['statusname'];
  3902. //$usermessage=user_message($userid);
  3903. $usermessage = $user['message'];
  3904. $bodytext = "Reassigning to original owner {$username} ({$userstatus})";
  3905. $assigntype = 'reassigning';
  3906. $risql = "INSERT INTO `{$dbUpdates}` (incidentid, userid, bodytext, type, timestamp, currentowner, currentstatus) ";
  3907. $risql .= "VALUES ('{$incident->id}', '0', '$bodytext', '$assigntype', '$now', ";
  3908. $risql .= "'{$backupid}', ";
  3909. $risql .= "'{$incident->status}')";
  3910. mysql_query($risql);
  3911. if (mysql_error()) trigger_error(mysql_error(),E_USER_ERROR);
  3912. // remove from assign queue now, all done
  3913. $rsql = "DELETE FROM `{$dbTempAssigns}` WHERE incidentid='{$assign->incidentid}' AND originalowner='{$assign->originalowner}'";
  3914. mysql_query($rsql);
  3915. if (mysql_error()) trigger_error(mysql_error(),E_USER_ERROR);
  3916. }
  3917. }
  3918. }
  3919. else
  3920. {
  3921. // now have a look to see if the reassign was completed
  3922. $ssql = "SELECT id FROM `{$dbIncidents}` WHERE id='{$assign->incidentid}' LIMIT 1";
  3923. $sresult = mysql_query($ssql);
  3924. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  3925. if (mysql_num_rows($sresult) >= 1)
  3926. {
  3927. // reassign wasn't completed, or it was already assigned back, simply remove from assign queue
  3928. $rsql = "DELETE FROM `{$dbTempAssigns}` WHERE incidentid='{$assign->incidentid}' AND originalowner='{$assign->originalowner}'";
  3929. mysql_query($rsql);
  3930. if (mysql_error()) trigger_error(mysql_error(),E_USER_ERROR);
  3931. }
  3932. }
  3933. }
  3934. }
  3935. return;
  3936. }
  3937. /**
  3938. * Format an external ID (From an escalation partner) as HTML
  3939. * @author Ivan Lucas
  3940. * @param int $externalid. An external ID to format
  3941. * @param int $escalationpath. Escalation path ID
  3942. * @returns HTML
  3943. */
  3944. function format_external_id($externalid, $escalationpath='')
  3945. {
  3946. global $CONFIG, $dbEscalationPaths;
  3947. if (!empty($escalationpath))
  3948. {
  3949. // Extract escalation path
  3950. $epsql = "SELECT id, name, track_url, home_url, url_title FROM `{$dbEscalationPaths}` ";
  3951. if (!empty($escalationpath)) $epsql .= "WHERE id='$escalationpath' ";
  3952. $epresult = mysql_query($epsql);
  3953. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  3954. if (mysql_num_rows($epresult) >= 1)
  3955. {
  3956. while ($escalationpath = mysql_fetch_object($epresult))
  3957. {
  3958. $epath['name'] = $escalationpath->name;
  3959. $epath['track_url'] = $escalationpath->track_url;
  3960. $epath['home_url'] = $escalationpath->home_url;
  3961. $epath['url_title'] = $escalationpath->url_title;
  3962. }
  3963. if (!empty($externalid))
  3964. {
  3965. $epathurl = str_replace('%externalid%',$externalid,$epath['track_url']);
  3966. $html = "<a href='{$epathurl}' title='{$epath['url_title']}'>{$externalid}</a>";
  3967. }
  3968. else
  3969. {
  3970. $epathurl = $epath['home_url'];
  3971. $html = "<a href='{$epathurl}' title='{$epath['url_title']}'>{$epath['name']}</a>";
  3972. }
  3973. }
  3974. }
  3975. else
  3976. {
  3977. $html = $externalid;
  3978. }
  3979. return $html;
  3980. }
  3981. // Converts a PHP.INI integer into a byte value
  3982. function return_bytes($val)
  3983. {
  3984. $val = trim($val);
  3985. $last = strtolower($val{strlen($val)-1});
  3986. switch ($last)
  3987. {
  3988. // The 'G' modifier is available since PHP 5.1.0
  3989. case 'g': $val *= 1024;
  3990. case 'm': $val *= 1024;
  3991. case 'k': $val *= 1024;
  3992. }
  3993. return $val;
  3994. }
  3995. // FIXME use this instead of hardcoding tabs
  3996. function draw_tabs($tabsarray, $selected='')
  3997. {
  3998. if ($selected=='') $selected=key($tabsarray);
  3999. $html .= "<div class='tabcontainer'>";
  4000. $html .= "<ul class='tabnav'>";
  4001. foreach ($tabsarray AS $tab => $url)
  4002. {
  4003. $html .= "<li><a href='$url'";
  4004. if (strtolower($tab) == strtolower($selected)) $html .= " class='active'";
  4005. $tab=str_replace('_', ' ', $tab);
  4006. $html .= ">$tab</a></li>\n";
  4007. }
  4008. $html .= "</ul>";
  4009. $html .= "</div>";
  4010. return ($html);
  4011. }
  4012. /**
  4013. * Identifies whether feedback should be send for this contract,
  4014. * This checks against $CONFIG['no_feedback_contracts'] to see if the contract is set to receive no feedback
  4015. * @param $contractid int The contract ID to check
  4016. * @return bool TRUE if feedback should be sent, false otherwise
  4017. * @author Paul Heaney
  4018. */
  4019. function send_feedback($contractid)
  4020. {
  4021. global $CONFIG;
  4022. foreach ($CONFIG['no_feedback_contracts'] AS $contract)
  4023. {
  4024. if ($contract == $contractid)
  4025. {
  4026. return FALSE;
  4027. }
  4028. }
  4029. return TRUE;
  4030. }
  4031. /**
  4032. * Creates a blank feedback form response
  4033. * @param $formid int The feedback form to use
  4034. * @param $incidentid int The incident to generate the form for
  4035. * @return int The form ID
  4036. */
  4037. function create_incident_feedback($formid, $incidentid)
  4038. {
  4039. global $dbFeedbackRespondents;
  4040. $contactid = incident_contact($incidentid);
  4041. $email = contact_email($contactid);
  4042. $sql = "INSERT INTO `{$dbFeedbackRespondents}` (formid, contactid, email, incidentid) VALUES (";
  4043. $sql .= "'".mysql_real_escape_string($formid)."', ";
  4044. $sql .= "'".mysql_real_escape_string($contactid)."', ";
  4045. $sql .= "'".mysql_real_escape_string($email)."', ";
  4046. $sql .= "'".mysql_real_escape_string($incidentid)."') ";
  4047. mysql_query($sql);
  4048. if (mysql_error()) trigger_error ("MySQL Error: ".mysql_error(), E_USER_ERROR);
  4049. $blankformid = mysql_insert_id();
  4050. return $blankformid;
  4051. }
  4052. function file_permissions_info($perms)
  4053. {
  4054. if (($perms & 0xC000) == 0xC000) $info = 's';
  4055. elseif (($perms & 0xA000) == 0xA000) $info = 'l';
  4056. elseif (($perms & 0x8000) == 0x8000) $info = '-';
  4057. elseif (($perms & 0x6000) == 0x6000) $info = 'b';
  4058. elseif (($perms & 0x4000) == 0x4000) $info = 'd';
  4059. elseif (($perms & 0x2000) == 0x2000) $info = 'c';
  4060. elseif (($perms & 0x1000) == 0x1000) $info = 'p';
  4061. else $info = 'u';
  4062. // Owner
  4063. $info .= (($perms & 0x0100) ? 'r' : '-');
  4064. $info .= (($perms & 0x0080) ? 'w' : '-');
  4065. $info .= (($perms & 0x0040) ?
  4066. (($perms & 0x0800) ? 's' : 'x' ) :
  4067. (($perms & 0x0800) ? 'S' : '-'));
  4068. // Group
  4069. $info .= (($perms & 0x0020) ? 'r' : '-');
  4070. $info .= (($perms & 0x0010) ? 'w' : '-');
  4071. $info .= (($perms & 0x0008) ?
  4072. (($perms & 0x0400) ? 's' : 'x' ) :
  4073. (($perms & 0x0400) ? 'S' : '-'));
  4074. // World
  4075. $info .= (($perms & 0x0004) ? 'r' : '-');
  4076. $info .= (($perms & 0x0002) ? 'w' : '-');
  4077. $info .= (($perms & 0x0001) ?
  4078. (($perms & 0x0200) ? 't' : 'x' ) :
  4079. (($perms & 0x0200) ? 'T' : '-'));
  4080. return $info;
  4081. }
  4082. function external_escalation($escalated, $incid)
  4083. {
  4084. foreach ($escalated as $i => $id)
  4085. {
  4086. if ($id == $incid)
  4087. {
  4088. return "yes";
  4089. }
  4090. }
  4091. return "no";
  4092. }
  4093. /**
  4094. * Converts BBcode to HTML
  4095. * @author Paul Heaney
  4096. * @param string $text. Text with BBCode
  4097. * @returns string HTML
  4098. */
  4099. function bbcode($text)
  4100. {
  4101. global $CONFIG;
  4102. $bbcode_regex = array(0 => "/\[b\](.*?)\[\/b\]/s",
  4103. 1 => "/\[i\](.*?)\[\/i\]/s",
  4104. 2 => "/\[u\](.*?)\[\/u\]/s",
  4105. 3 => "/\[quote\](.*?)\[\/quote\]/s",
  4106. 4 => "/\[size=(.+?)\](.+?)\[\/size\]/is",
  4107. //5 => "/\[url\](.*?)\[\/url\]/s",
  4108. 6 => "/\[size=(.+?)\](.+?)\[\/size\]/is",
  4109. 7 => "/\[img\](.*?)\[\/img\]/s",
  4110. 8 => "/\[size=(.+?)\](.+?)\[\/size\]/is",
  4111. 9 => "/\[color\](.*?)\[\/color\]/s",
  4112. 10 => "/\[size=(.+?)\](.+?)\[\/size\]/is",
  4113. 11 => "/\[size\](.*?)\[\/size\]/s",
  4114. 12 => "/\[code\](.*?)\[\/code\]/s",
  4115. 13 => "/\[hr\]/s",
  4116. 14 => "/\[s\](.*?)\[\/s\]/s",
  4117. 15 => "/\[\[att\=(.*?)]](.*?)\[\[\/att]]/s",
  4118. 16 => "/\[url=(.+?)\](.+?)\[\/url\]/is");
  4119. $bbcode_replace = array(0 => "<strong>$1</strong>",
  4120. 1 => "<em>$1</em>",
  4121. 2 => "<u>$1</u>",
  4122. 3 => "<blockquote><p>$1</p></blockquote>",
  4123. 4 => "<blockquote cite=\"$1\"><p>$1 said:<br />$2</p></blockquote>",
  4124. //5 => '<a href="$1" title="$1">$1</a>',
  4125. 6 => "<a href=\"$1\" title=\"$1\">$2</a>",
  4126. 7 => "<img src=\"$1\" alt=\"User submitted image\" />",
  4127. 8 => "<span style=\"color:$1\">$2</span>",
  4128. 9 => "<span style=\"color:red;\">$1</span>",
  4129. 10 => "<span style=\"font-size:$1\">$2</span>",
  4130. 11 => "<span style=\"font-size:large\">$1</span>",
  4131. 12 => "<code>$1</code>",
  4132. 13 => "<hr />",
  4133. 14 => "<span style=\"text-decoration:line-through\">$1</span>",
  4134. 15 => "<a href=\"{$CONFIG['application_webpath']}download.php?id=$1\">$2</a>",
  4135. 16 => "<a href=\"$1\">$2</a>");
  4136. $html = preg_replace($bbcode_regex, $bbcode_replace, $text);
  4137. return $html;
  4138. }
  4139. function strip_bbcode_tooltip($text)
  4140. {
  4141. $bbcode_regex = array(0 => '/\[url\](.*?)\[\/url\]/s',
  4142. 1 => '/\[url\=(.*?)\](.*?)\[\/url\]/s',
  4143. 2 => '/\[color\=(.*?)\](.*?)\[\/color\]/s',
  4144. 3 => '/\[size\=(.*?)\](.*?)\[\/size\]/s',
  4145. 4 => '/\[blockquote\=(.*?)\](.*?)\[\/blockquote\]/s',
  4146. 5 => '/\[blockquote\](.*?)\[\/blockquote\]/s',
  4147. 6 => "/\[s\](.*?)\[\/s\]/s");
  4148. $bbcode_replace = array(0 => '$1',
  4149. 1 => '$2',
  4150. 2 => '$2',
  4151. 3 => '$2',
  4152. 4 => '$2',
  4153. 5 => '$1',
  4154. 6 => '$1'
  4155. );
  4156. return preg_replace($bbcode_regex, $bbcode_replace, $text);
  4157. }
  4158. /**
  4159. * Produces a HTML toolbar for use with a textarea or input box for entering bbcode
  4160. * @author Ivan Lucas
  4161. * @param string $elementid. HTML element ID of the textarea or input
  4162. * @returns string HTML
  4163. */
  4164. function bbcode_toolbar($elementid)
  4165. {
  4166. $html = "\n<div class='bbcode_toolbar'>BBCode: ";
  4167. $html .= "<a href=\"javascript:insertBBCode('{$elementid}', '[b]', '[/b]')\">B</a> ";
  4168. $html .= "<a href=\"javascript:insertBBCode('{$elementid}', '[i]', '[/i]')\">I</a> ";
  4169. $html .= "<a href=\"javascript:insertBBCode('{$elementid}', '[u]', '[/u]')\">U</a> ";
  4170. $html .= "<a href=\"javascript:insertBBCode('{$elementid}', '[s]', '[/s]')\">S</a> ";
  4171. $html .= "<a href=\"javascript:insertBBCode('{$elementid}', '[quote]', '[/quote]')\">Quote</a> ";
  4172. $html .= "<a href=\"javascript:insertBBCode('{$elementid}', '[url]', '[/url]')\">Link</a> ";
  4173. $html .= "<a href=\"javascript:insertBBCode('{$elementid}', '[img]', '[/img]')\">Img</a> ";
  4174. $html .= "<a href=\"javascript:insertBBCode('{$elementid}', '[color]', '[/color]')\">Color</a> ";
  4175. $html .= "<a href=\"javascript:insertBBCode('{$elementid}', '[size]', '[/size]')\">Size</a> ";
  4176. $html .= "<a href=\"javascript:insertBBCode('{$elementid}', '[code]', '[/code]')\">Code</a> ";
  4177. $html .= "<a href=\"javascript:insertBBCode('{$elementid}', '', '[hr]')\">HR</a> ";
  4178. $html .= "</div>\n";
  4179. return $html;
  4180. }
  4181. function parse_updatebody($updatebody, $striptags = TRUE)
  4182. {
  4183. if (!empty($updatebody))
  4184. {
  4185. $updatebody = str_replace("&lt;hr&gt;", "[hr]\n", $updatebody);
  4186. if ($striptags)
  4187. {
  4188. $updatebody = strip_tags($updatebody);
  4189. }
  4190. else
  4191. {
  4192. $updatebody = str_replace("<hr>", "", $updatebody);
  4193. }
  4194. $updatebody = nl2br($updatebody);
  4195. $updatebody = str_replace("&amp;quot;", "&quot;", $updatebody);
  4196. $updatebody = str_replace("&amp;gt;", "&gt;", $updatebody);
  4197. $updatebody = str_replace("&amp;lt;", "&lt;", $updatebody);
  4198. // Insert path to attachments
  4199. //new style
  4200. $updatebody = preg_replace("/\[\[att\=(.*?)\]\](.*?)\[\[\/att\]\]/","$2", $updatebody);
  4201. //old style
  4202. $updatebody = preg_replace("/\[\[att\]\](.*?)\[\[\/att\]\]/","$1", $updatebody);
  4203. //remove tags that are incompatable with tool tip
  4204. $updatebody = strip_bbcode_tooltip($updatebody);
  4205. //then show compatable BBCode
  4206. $updatebody = bbcode($updatebody);
  4207. if (strlen($updatebody) > 490) $updatebody .= '...';
  4208. }
  4209. return $updatebody;
  4210. }
  4211. /**
  4212. * Produces a HTML form for adding a note to an item
  4213. * @param $linkid int The link type to be used
  4214. * @param $refid int The ID of the item this note if for
  4215. * @return string The HTML to display
  4216. */
  4217. function add_note_form($linkid, $refid)
  4218. {
  4219. global $now, $sit, $iconset;
  4220. $html = "<form name='addnote' action='note_add.php' method='post'>";
  4221. $html .= "<div class='detailhead note'> <div class='detaildate'>".readable_date($now)."</div>\n";
  4222. $html .= icon('note', 16, $GLOBALS['strNote ']);
  4223. $html .= " ".sprintf($GLOBALS['strNewNoteByX'], user_realname($sit[2]))."</div>\n";
  4224. $html .= "<div class='detailentry note'>";
  4225. $html .= "<textarea rows='3' cols='40' name='bodytext' style='width: 94%; margin-top: 5px; margin-bottom: 5px; margin-left: 3%; margin-right: 3%; background-color: transparent; border: 1px dashed #A2A86A;'></textarea>";
  4226. if (!empty($linkid))
  4227. {
  4228. $html .= "<input type='hidden' name='link' value='{$linkid}' />";
  4229. }
  4230. else
  4231. {
  4232. $html .= "&nbsp;{$GLOBALS['strLInk']} <input type='text' name='link' size='3' />";
  4233. }
  4234. if (!empty($refid))
  4235. {
  4236. $html .= "<input type='hidden' name='refid' value='{$refid}' />";
  4237. }
  4238. else
  4239. {
  4240. $html .= "&nbsp;{$GLOBALS['strRefID']} <input type='text' name='refid' size='4' />";
  4241. }
  4242. $html .= "<input type='hidden' name='action' value='addnote' />";
  4243. $html .= "<input type='hidden' name='rpath' value='{$_SERVER['PHP_SELF']}?{$_SERVER['QUERY_STRING']}' />";
  4244. $html .= "<div style='text-align: right'><input type='submit' value='{$GLOBALS['strAddNote']}' /></div>\n";
  4245. $html .= "</div>\n";
  4246. $html .= "</form>";
  4247. return $html;
  4248. }
  4249. /**
  4250. * Produces HTML of all notes assigned to an item
  4251. * @param $linkid int The link type
  4252. * @param $refid int The ID of the item the notes are linked to
  4253. * @param $delete bool Whether its possible to delet notes (default TRUE)
  4254. * @return string HTML of the notes
  4255. */
  4256. function show_notes($linkid, $refid, $delete = TRUE)
  4257. {
  4258. global $sit, $iconset, $dbNotes;
  4259. $sql = "SELECT * FROM `{$dbNotes}` WHERE link='{$linkid}' AND refid='{$refid}' ORDER BY timestamp DESC, id DESC";
  4260. $result = mysql_query($sql);
  4261. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  4262. $countnotes = mysql_num_rows($result);
  4263. if ($countnotes >= 1)
  4264. {
  4265. while ($note = mysql_fetch_object($result))
  4266. {
  4267. $html .= "<div class='detailhead note'> <div class='detaildate'>".readable_date(mysqlts2date($note->timestamp));
  4268. if ($delete)
  4269. {
  4270. $html .= "<a href='note_delete.php?id={$note->id}&amp;rpath=";
  4271. $html .= "{$_SERVER['PHP_SELF']}?{$_SERVER['QUERY_STRING']}' ";
  4272. $html .= "onclick=\"return confirm_action('{$strAreYouSureDelete}');\">";
  4273. $html .= icon('delete', 16)."</a>";
  4274. }
  4275. $html .= "</div>\n"; // /detaildate
  4276. $html .= icon('note', 16)." ";
  4277. $html .= sprintf($GLOBALS['strNoteAddedBy'], user_realname($note->userid,TRUE));
  4278. $html .= "</div>\n"; // detailhead
  4279. $html .= "<div class='detailentry note'>";
  4280. $html .= nl2br(bbcode($note->bodytext));
  4281. $html .= "</div>\n";
  4282. }
  4283. }
  4284. return $html;
  4285. }
  4286. /**
  4287. * Produces a HTML dashlet 'window' for display on the dashboard
  4288. * @author Ivan Lucas
  4289. * @param string $dashboard. Dashboard component name.
  4290. * @param string $dashletid. The table row ID of that we are 'drawing' this dashlet into and
  4291. * the ID of the dashboard component instance as recorded in the users settings
  4292. * as a single string, this is received by the dashlet from dashboard_do()
  4293. * @param string $icon. HTML for an icon to be displayed on the dashlet window
  4294. * @param string $title. A title for the dashlet, also displayed on the dashlet window
  4295. * @param string $link. URL of a page to link to from the dashlet window (link on the title)
  4296. * @param string $content. HTML content to display inside the dashlet window
  4297. * @note This function looks for the existence of two dashboard component functions
  4298. * dashboard_*_display() and dashboard_*_edit(), (where * is the name of the dashlet)
  4299. * if these are found the dashlet will use ajax and call these functions for it's
  4300. * main display (and refreshing) and to edit settings.
  4301. * @returns string HTML
  4302. */
  4303. function dashlet($dashboard, $dashletid, $icon, $title='', $link='', $content='')
  4304. {
  4305. global $strLoading;
  4306. if (empty($icon)) $icon = icon('dashboard', 16);
  4307. if (empty($title)) $title = $GLOBALS['strUntitled'];
  4308. $displayfn = "dashboard_{$dashboard}_display";
  4309. $editfn = "dashboard_{$dashboard}_edit";
  4310. $html .= "<div class='windowbox' id='{$dashletid}'>";
  4311. $html .= "<div class='windowtitle'>";
  4312. $html .= "<div class='innerwindow'>";
  4313. if (function_exists($displayfn))
  4314. {
  4315. $html .= "<a href=\"javascript:get_and_display('ajaxdata.php?action=dashboard_display&amp;dashboard={$dashboard}&amp;did={$dashletid}','win{$dashletid}',true);\">";
  4316. $html .= icon('reload', 16, '', '', "refresh{$dashletid}")."</a>";
  4317. }
  4318. if (function_exists($editfn))
  4319. {
  4320. $html .= "<a href=\"javascript:get_and_display('ajaxdata.php?action=dashboard_edit&amp;dashboard={$dashboard}&amp;did={$dashletid}','win{$dashletid}',false);\">";
  4321. $html .= icon('edit', 16)."</a>";
  4322. }
  4323. $html .= "</div>";
  4324. if (!empty($link)) $html .= "<a href=\"{$link}\">{$icon}</a> <a href=\"{$link}\">{$title}</a>";
  4325. else $html .= "{$icon} {$title}";
  4326. $html .= "</div>\n";
  4327. $html .= "<div class='window' id='win{$dashletid}'>";
  4328. $html .= $content;
  4329. $displayfn = "dashboard_{$dashboard}_display";
  4330. if (function_exists($displayfn))
  4331. {
  4332. $html .= "<script type='text/javascript'>\n//<![CDATA[\nget_and_display('ajaxdata.php?action=dashboard_display&dashboard={$dashboard}','win{$dashletid}',true);\n//]]>\n</script>\n";
  4333. }
  4334. $html .= "</div></div>";
  4335. return $html;
  4336. }
  4337. /**
  4338. * Creates a link that opens within a dashlet window
  4339. * @author Ivan Lucas
  4340. * @param string $dashboard. Dashboard component name.
  4341. * @param string $dashletid. The table row ID of that we are 'drawing' this dashlet into and
  4342. * the ID of the dashboard component instance as recorded in the users settings
  4343. * as a single string, this is received by the dashlet from dashboard_do()
  4344. * @param string $text. The text of the hyperlink for the user to click
  4345. * @param string $action. edit|save|display
  4346. edit = This is a link to a dashlet config form page
  4347. save = Submit a dashlet config form (see $formid param)
  4348. display = Display a regular dashlet page
  4349. * @param array $params. Associative array of parameters to pass on the URL of the link
  4350. * @param bool $refresh. The link will be automatically refreshed when TRUE
  4351. * @param string $formid. The form element ID to be submitted when using 'save' action
  4352. * @returns string HTML
  4353. */
  4354. function dashlet_link($dashboard, $dashletid, $text='', $action='', $params='', $refresh = FALSE, $formid='')
  4355. {
  4356. if ($action == 'edit') $action = 'dashboard_edit';
  4357. elseif ($action == 'save') $action = 'dashboard_save';
  4358. else $action = 'dashboard_display';
  4359. if (empty($text)) $text = $GLOBALS['strUntitled'];
  4360. // Ensure the dashlet ID is always correct, 'win' gets prepended with each subpage
  4361. // We only need it once
  4362. $dashletid = 'win'.str_replace('win', '', $dashletid);
  4363. // Convert refresh boolean to javascript text for boolean
  4364. if ($refresh) $refresh = 'true';
  4365. else $refresh = 'false';
  4366. if ($action == 'dashboard_save' AND $formid == '') $formid = "{$dashboard}form";
  4367. if ($action == 'dashboard_save') $html .= "<a href=\"javascript:ajax_save(";
  4368. else $html .= "<a href=\"javascript:get_and_display(";
  4369. $html .= "'ajaxdata.php?action={$action}&dashboard={$dashboard}&did={$dashletid}";
  4370. if (is_array($params))
  4371. {
  4372. foreach ($params AS $pname => $pvalue)
  4373. {
  4374. $html .= "&{$pname}={$pvalue}";
  4375. }
  4376. }
  4377. //$html .= "&editaction=do_add&type={$type}";
  4378. if ($action != 'dashboard_save')
  4379. {
  4380. $html .= "', '{$dashletid}'";
  4381. $html .= ", $refresh";
  4382. }
  4383. else
  4384. {
  4385. $html .= "', '{$formid}'";
  4386. }
  4387. $html .= ");\">{$text}</a>";
  4388. return $html;
  4389. }
  4390. /**
  4391. * Wrapper function to call dashboard_*_do() within a dashlet plugin
  4392. * See dashlet() for more information
  4393. * @author Ivan Lucas
  4394. * @param string $context
  4395. * @param string $row
  4396. * @param string $dashboardid
  4397. */
  4398. function dashboard_do($context, $row=0, $dashboardid=0)
  4399. {
  4400. global $DASHBOARDCOMP;
  4401. $dashletid = "{$row}-{$dashboardid}";
  4402. $action = $DASHBOARDCOMP[$context];
  4403. if ($action != NULL || $action != '')
  4404. {
  4405. if (function_exists($action)) $action($dashletid);
  4406. }
  4407. }
  4408. function show_dashboard_component($row, $dashboardid)
  4409. {
  4410. global $dbDashboard;
  4411. $sql = "SELECT name FROM `{$dbDashboard}` WHERE enabled = 'true' AND id = '$dashboardid'";
  4412. $result = mysql_query($sql);
  4413. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  4414. if (mysql_num_rows($result) == 1)
  4415. {
  4416. $obj = mysql_fetch_object($result);
  4417. dashboard_do("dashboard_".$obj->name, 'db_'.$row, $dashboardid);
  4418. }
  4419. }
  4420. /**
  4421. * Recursive function to list links as a tree
  4422. * @author Ivan Lucas
  4423. */
  4424. function show_links($origtab, $colref, $level=0, $parentlinktype='', $direction='lr')
  4425. {
  4426. global $dbLinkTypes, $dbLinks;
  4427. // Maximum recursion
  4428. $maxrecursions = 15;
  4429. if ($level <= $maxrecursions)
  4430. {
  4431. $sql = "SELECT * FROM `{$dbLinkTypes}` WHERE origtab='$origtab' ";
  4432. if (!empty($parentlinktype)) $sql .= "AND id='{$parentlinktype}'";
  4433. $result = mysql_query($sql);
  4434. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  4435. while ($linktype = mysql_fetch_object($result))
  4436. {
  4437. // Look up links of this type
  4438. $lsql = "SELECT * FROM `{$dbLinks}` WHERE linktype='{$linktype->id}' ";
  4439. if ($direction=='lr') $lsql .= "AND origcolref='{$colref}'";
  4440. elseif ($direction=='rl') $lsql .= "AND linkcolref='{$colref}'";
  4441. $lresult = mysql_query($lsql);
  4442. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  4443. if (mysql_num_rows($lresult) >= 1)
  4444. {
  4445. if (mysql_num_rows($lresult) >= 1)
  4446. {
  4447. $html .= "<ul>";
  4448. $html .= "<li>";
  4449. while ($link = mysql_fetch_object($lresult))
  4450. {
  4451. $recsql = "SELECT {$linktype->selectionsql} AS recordname FROM {$linktype->linktab} WHERE ";
  4452. if ($direction=='lr') $recsql .= "{$linktype->linkcol}='{$link->linkcolref}' ";
  4453. elseif ($direction=='rl') $recsql .= "{$linktype->origcol}='{$link->origcolref}' ";
  4454. $recresult = mysql_query($recsql);
  4455. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  4456. while ($record = mysql_fetch_object($recresult))
  4457. {
  4458. if ($link->direction == 'bi')
  4459. {
  4460. $html .= "<strong>{$linktype->name}</strong> ";
  4461. }
  4462. elseif ($direction == 'lr')
  4463. {
  4464. $html .= "<strong>{$linktype->lrname}</strong> ";
  4465. }
  4466. elseif ($direction == 'rl')
  4467. {
  4468. $html .= "<strong>{$linktype->rlname}</strong> ";
  4469. }
  4470. else
  4471. {
  4472. $html = $GLOBALS['strError'];
  4473. }
  4474. if ($direction == 'lr')
  4475. {
  4476. $currentlinkref = $link->linkcolref;
  4477. }
  4478. elseif ($direction == 'rl')
  4479. {
  4480. $currentlinkref = $link->origcolref;
  4481. }
  4482. $viewurl = str_replace('%id%',$currentlinkref,$linktype->viewurl);
  4483. $html .= "{$currentlinkref}: ";
  4484. if (!empty($viewurl)) $html .= "<a href='$viewurl'>";
  4485. $html .= "{$record->recordname}";
  4486. if (!empty($viewurl)) $html .= "</a>";
  4487. $html .= " - ".user_realname($link->userid,TRUE);
  4488. $html .= show_links($linktype->linktab, $currentlinkref, $level+1, $linktype->id, $direction); // Recurse
  4489. $html .= "</li>\n";
  4490. }
  4491. }
  4492. $html .= "</ul>\n";
  4493. }
  4494. else $html .= "<p>{$GLOBALS['strNone']}</p>";
  4495. }
  4496. }
  4497. }
  4498. else $html .= "<p class='error'>{$GLOBALS['strError']}: Maximum number of {$maxrecursions} recursions reached</p>";
  4499. return $html;
  4500. }
  4501. /**
  4502. * Interface for creating record 'links' (relationships)
  4503. * @author Ivan Lucas
  4504. */
  4505. function show_create_links($table, $ref)
  4506. {
  4507. global $dbLinkTypes;
  4508. $html .= "<p align='center'>{$GLOBALS['strAddLink']}: ";
  4509. $sql = "SELECT * FROM `{$dbLinkTypes}` WHERE origtab='$table' OR linktab='$table' ";
  4510. $result = mysql_query($sql);
  4511. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  4512. $numlinktypes = mysql_num_rows($result);
  4513. $rowcount = 1;
  4514. while ($linktype = mysql_fetch_object($result))
  4515. {
  4516. if ($linktype->origtab == $table AND $linktype->linktab != $table)
  4517. {
  4518. $html .= "<a href='link_add.php?origtab=tasks&amp;origref={$ref}&amp;linktype={$linktype->id}'>{$linktype->lrname}</a>";
  4519. }
  4520. elseif ($linktype->origtab != $table AND $linktype->linktab == $table)
  4521. {
  4522. $html .= "<a href='link_add.php?origtab=tasks&amp;origref={$ref}&amp;linktype={$linktype->id}'>{$linktype->rlname}</a>";
  4523. }
  4524. else
  4525. {
  4526. $html .= "<a href='link_add.php?origtab=tasks&amp;origref={$ref}&amp;linktype={$linktype->id}'>{$linktype->lrname}</a> | ";
  4527. $html .= "<a href='link_add.php?origtab=tasks&amp;origref={$ref}&amp;linktype={$linktype->id}&amp;dir=rl'>{$linktype->rlname}</a>";
  4528. }
  4529. if ($rowcount < $numlinktypes) $html .= " | ";
  4530. $rowcount++;
  4531. }
  4532. $html .= "</p>";
  4533. return $html;
  4534. }
  4535. /**
  4536. * Create a PNG chart
  4537. * @author Ivan Lucas
  4538. * @param string $type. The type of chart to draw. (e.g. 'pie').
  4539. * @return resource a PNG image resource
  4540. * @note Currently only has proper support for pie charts (type='pie')
  4541. * @todo TODO Support for bar and line graphs
  4542. */
  4543. function draw_chart_image($type, $width, $height, $data, $legends, $title='', $unit='')
  4544. {
  4545. global $CONFIG;
  4546. // Graph settings
  4547. if (empty($width)) $width = 500;
  4548. if (empty($height)) $height = 150;
  4549. $fontfile = dirname( __FILE__ ).DIRECTORY_SEPARATOR."FreeSans.ttf"; // FIXME font file!
  4550. if (!empty($fontfile) AND file_exists($fontfile)) $use_ttf = TRUE;
  4551. else $use_ttf = FALSE;
  4552. $countdata = count($data);
  4553. $sumdata = array_sum($data);
  4554. if ($countdata > 8) $height += (($countdata - 8) * 14);
  4555. $img = imagecreatetruecolor($width, $height);
  4556. $white = imagecolorallocate($img, 255, 255, 255);
  4557. $blue = imagecolorallocate($img, 240, 240, 255);
  4558. $midblue = imagecolorallocate($img, 204, 204, 255);
  4559. $darkblue = imagecolorallocate($img, 32, 56, 148);
  4560. $black = imagecolorallocate($img, 0, 0, 0);
  4561. $grey = imagecolorallocate($img, 224, 224, 224);
  4562. $red = imagecolorallocate($img, 255, 0, 0);
  4563. imagefill($img, 0, 0, $white);
  4564. $rgb[] = "190,190,255";
  4565. $rgb[] = "205,255,255";
  4566. $rgb[] = "255,255,156";
  4567. $rgb[] = "156,255,156";
  4568. $rgb[] = "255,205,195";
  4569. $rgb[] = "255,140,255";
  4570. $rgb[] = "100,100,155";
  4571. $rgb[] = "98,153,90";
  4572. $rgb[] = "205,210,230";
  4573. $rgb[] = "192,100,100";
  4574. $rgb[] = "204,204,0";
  4575. $rgb[] = "255,102,102";
  4576. $rgb[] = "0,204,204";
  4577. $rgb[] = "0,255,0";
  4578. $rgb[] = "255,168,88";
  4579. $rgb[] = "128,0,128";
  4580. $rgb[] = "0,153,153";
  4581. $rgb[] = "255,230,204";
  4582. $rgb[] = "128,170,213";
  4583. $rgb[] = "75,75,75";
  4584. // repeats...
  4585. $rgb[] = "190,190,255";
  4586. $rgb[] = "156,255,156";
  4587. $rgb[] = "255,255,156";
  4588. $rgb[] = "205,255,255";
  4589. $rgb[] = "255,205,195";
  4590. $rgb[] = "255,140,255";
  4591. $rgb[] = "100,100,155";
  4592. $rgb[] = "98,153,90";
  4593. $rgb[] = "205,210,230";
  4594. $rgb[] = "192,100,100";
  4595. $rgb[] = "204,204,0";
  4596. $rgb[] = "255,102,102";
  4597. $rgb[] = "0,204,204";
  4598. $rgb[] = "0,255,0";
  4599. $rgb[] = "255,168,88";
  4600. $rgb[] = "128,0,128";
  4601. $rgb[] = "0,153,153";
  4602. $rgb[] = "255,230,204";
  4603. $rgb[] = "128,170,213";
  4604. $rgb[] = "75,75,75";
  4605. switch ($type)
  4606. {
  4607. case 'pie':
  4608. $cx = '120';$cy ='60'; //Set Pie Postition. CenterX,CenterY
  4609. $sx = '200';$sy='100';$sz ='15';// Set Size-dimensions. SizeX,SizeY,SizeZ
  4610. // Title
  4611. if (!empty($title))
  4612. {
  4613. $cy += 10;
  4614. if ($use_ttf) imagettftext($img, 10, 0, 2, 10, $black, $fontfile, $title);
  4615. else imagestring($img,2, 2, ($legendY-1), "{$title}", $black);
  4616. }
  4617. //convert to angles.
  4618. for ($i=0;$i<=$countdata;$i++)
  4619. {
  4620. $angle[$i] = (($data[$i] / $sumdata) * 360);
  4621. $angle_sum[$i] = array_sum($angle);
  4622. }
  4623. $background = imagecolorallocate($img, 255, 255, 255);
  4624. //Random colors.
  4625. for ($i=0;$i<=$countdata;$i++)
  4626. {
  4627. $rgbcolors = explode(',',$rgb[$i]);
  4628. $colors[$i] = imagecolorallocate($img,$rgbcolors[0],$rgbcolors[1],$rgbcolors[2]);
  4629. $colord[$i] = imagecolorallocate($img,($rgbcolors[0]/1.5),($rgbcolors[1]/1.5),($rgbcolors[2]/1.5));
  4630. }
  4631. //3D effect.
  4632. $legendY = 80 - ($countdata * 10);
  4633. if ($legendY < 10) $legendY = 10;
  4634. for ($z=1; $z <= $sz; $z++)
  4635. {
  4636. for ($i=0;$i<$countdata;$i++)
  4637. {
  4638. imagefilledarc($img,$cx,($cy+$sz)-$z,$sx,$sy,$angle_sum[$i-1],$angle_sum[$i],$colord[$i],IMG_ARC_PIE);
  4639. }
  4640. }
  4641. imagerectangle($img, 250, $legendY-5, 470, $legendY+($countdata*15), $black);
  4642. //Top pie.
  4643. for ($i = 0; $i < $countdata; $i++)
  4644. {
  4645. imagefilledarc($img,$cx,$cy,$sx,$sy,$angle_sum[$i-1] ,$angle_sum[$i], $colors[$i], IMG_ARC_PIE);
  4646. imagefilledrectangle($img, 255, ($legendY+1), 264, ($legendY+9), $colors[$i]);
  4647. // Legend
  4648. if ($unit == 'seconds')
  4649. {
  4650. $data[$i]=format_seconds($data[$i]);
  4651. }
  4652. if ($use_ttf)
  4653. {
  4654. imagettftext($img, 8, 0, 270, ($legendY+9), $black, $fontfile, substr(urldecode($legends[$i]),0,27)." ({$data[$i]})");
  4655. }
  4656. else
  4657. {
  4658. imagestring($img,2, 270, ($legendY-1), substr(urldecode($legends[$i]),0,27)." ({$data[$i]})", $black);
  4659. }
  4660. // imagearc($img,$cx,$cy,$sx,$sy,$angle_sum[$i1] ,$angle_sum[$i], $blue);
  4661. $legendY+=15;
  4662. }
  4663. break;
  4664. case 'line':
  4665. $maxdata = 0;
  4666. $colwidth=round($width/$countdata);
  4667. $rowheight=round($height/10);
  4668. foreach ($data AS $dataval)
  4669. {
  4670. if ($dataval > $maxdata) $maxdata = $dataval;
  4671. }
  4672. imagerectangle($img, $width-1, $height-1, 0, 0, $black);
  4673. for ($i=1; $i<$countdata; $i++)
  4674. {
  4675. imageline($img, $i*$colwidth, 0, $i*$colwidth, $width, $grey);
  4676. imageline($img, 2, $i*$rowheight, $width-2, $i*$rowheight, $grey);
  4677. }
  4678. for ($i=0; $i<$countdata; $i++)
  4679. {
  4680. $dataheight=($height-($data[$i] / $maxdata) * $height);
  4681. $legendheight = $dataheight > ($height - 15) ? $height - 15 : $dataheight;
  4682. $nextdataheight=($height-($data[$i+1] / $maxdata) * $height);
  4683. imageline($img, $i*$colwidth, $dataheight, ($i+1)*$colwidth, $nextdataheight, $red);
  4684. imagestring($img, 3, $i*$colwidth, $legendheight, substr($legends[$i],0,6), $darkblue);
  4685. }
  4686. imagestring($img,3, 10, 10, $title, $red);
  4687. break;
  4688. case 'bar':
  4689. $maxdata = 0;
  4690. $colwidth=round($width/$countdata);
  4691. $rowheight=round($height/10);
  4692. foreach ($data AS $dataval)
  4693. {
  4694. if ($dataval > $maxdata) $maxdata = $dataval;
  4695. }
  4696. imagerectangle($img, $width-1, $height-1, 0, 0, $black);
  4697. for ($i=1; $i<$countdata; $i++)
  4698. {
  4699. imageline($img, $i*$colwidth, 0, $i*$colwidth, $width, $grey);
  4700. imageline($img, 2, $i*$rowheight, $width-2, $i*$rowheight, $grey);
  4701. }
  4702. for ($i=0; $i<$countdata; $i++)
  4703. {
  4704. $dataheight=($height-($data[$i] / $maxdata) * $height);
  4705. $legendheight = $dataheight > ($height - 15) ? $height - 15 : $dataheight;
  4706. imagefilledrectangle($img, $i*$colwidth, $dataheight, ($i+1)*$colwidth, $height, $darkblue);
  4707. imagefilledrectangle($img, ($i*$colwidth)+1, $dataheight+1, (($i+1)*$colwidth)-3, ($height-2), $midblue);
  4708. imagestring($img, 3, ($i*$colwidth)+4, $legendheight, substr($legends[$i],0,5), $darkblue);
  4709. }
  4710. imagestring($img,3, 10, 10, $title, $red);
  4711. break;
  4712. default:
  4713. imagerectangle($img, $width-1, $height-1, 1, 1, $red);
  4714. imagestring($img,3, 10, 10, "Invalid chart type", $red);
  4715. }
  4716. // Return a PNG image
  4717. return $img;
  4718. }
  4719. /**
  4720. * @author Paul Heaney
  4721. */
  4722. function display_drafts($type, $result)
  4723. {
  4724. global $iconset;
  4725. global $id;
  4726. global $CONFIG;
  4727. if ($type == 'update')
  4728. {
  4729. $page = "incident_update.php";
  4730. $editurlspecific = '';
  4731. }
  4732. else if ($type == 'email')
  4733. {
  4734. $page = "incident_email.php";
  4735. $editurlspecific = "&amp;step=2";
  4736. }
  4737. echo "<p align='center'>{$GLOBALS['strDraftChoose']}</p>";
  4738. $html = '';
  4739. while ($obj = mysql_fetch_object($result))
  4740. {
  4741. $html .= "<div class='detailhead'>";
  4742. $html .= "<div class='detaildate'>".date($CONFIG['dateformat_datetime'], $obj->lastupdate);
  4743. $html .= "</div>";
  4744. $html .= "<a href='{$page}?action=editdraft&amp;draftid={$obj->id}&amp;id={$id}{$editurlspecific}' class='info'>";
  4745. $html .= icon('edit', 16, $GLOBALS['strDraftEdit'])."</a>";
  4746. $html .= "<a href='{$page}?action=deletedraft&amp;draftid={$obj->id}&amp;id={$id}' class='info'>";
  4747. $html .= icon('delete', 16, $GLOBALS['strDraftDelete'])."</a>";
  4748. $html .= "</div>";
  4749. $html .= "<div class='detailentry'>";
  4750. $html .= nl2br($obj->content)."</div>";
  4751. }
  4752. return $html;
  4753. }
  4754. function ansort($x,$var,$cmp='strcasecmp')
  4755. {
  4756. // Numeric descending sort of multi array
  4757. if ( is_string($var) ) $var = "'$var'";
  4758. if ($cmp=='numeric')
  4759. {
  4760. uasort($x, create_function('$a,$b', 'return '.'( $a['.$var.'] < $b['.$var.']);'));
  4761. }
  4762. else
  4763. {
  4764. uasort($x, create_function('$a,$b', 'return '.$cmp.'( $a['.$var.'],$b['.$var.']);'));
  4765. }
  4766. return $x;
  4767. }
  4768. function array_remove_duplicate($array, $field)
  4769. {
  4770. foreach ($array as $sub)
  4771. {
  4772. $cmp[] = $sub[$field];
  4773. }
  4774. $unique = array_unique($cmp);
  4775. foreach ($unique as $k => $rien)
  4776. {
  4777. $new[] = $array[$k];
  4778. }
  4779. return $new;
  4780. }
  4781. function array_multi_search($needle, $haystack, $searchkey)
  4782. {
  4783. foreach ($haystack AS $thekey => $thevalue)
  4784. {
  4785. if ($thevalue[$searchkey] == $needle) return $thekey;
  4786. }
  4787. return FALSE;
  4788. }
  4789. // Implode assocative array
  4790. function implode_assoc($glue1, $glue2, $array)
  4791. {
  4792. foreach ($array as $key => $val)
  4793. {
  4794. $array2[] = $key.$glue1.$val;
  4795. }
  4796. return implode($glue2, $array2);
  4797. }
  4798. /**
  4799. * @author Kieran Hogg
  4800. * @param string $name. name of the html entity
  4801. * @param string $time. the time to set it to, format 12:34
  4802. * @returns string. HTML
  4803. */
  4804. function time_dropdown($name, $time='')
  4805. {
  4806. if ($time)
  4807. {
  4808. $time = explode(':', $time);
  4809. }
  4810. $html = "<select name='$name'>\n";
  4811. $html .= "<option></option>";
  4812. for ($hours = 0; $hours < 24; $hours++)
  4813. {
  4814. for ($mins = 0; $mins < 60; $mins+=15)
  4815. {
  4816. $hours = str_pad($hours, 2, "0", STR_PAD_LEFT);
  4817. $mins = str_pad($mins, 2, "0", STR_PAD_RIGHT);
  4818. if ($time AND $time[0] == $hours AND $time[1] == $mins)
  4819. {
  4820. $html .= "<option selected='selected' value='$hours:$mins'>$hours:$mins</option>";
  4821. }
  4822. else
  4823. {
  4824. if ($time AND $time[0] == $hours AND $time[1] < $mins AND $time[1] > ($mins - 15))
  4825. {
  4826. $html .= "<option selected='selected' value='$time[0]:$time[1]'>$time[0]:$time[1]</option>\n";
  4827. }
  4828. else
  4829. {
  4830. $html .= "<option value='$hours:$mins'>$hours:$mins</option>\n";
  4831. }
  4832. }
  4833. }
  4834. }
  4835. $html .= "</select>";
  4836. return $html;
  4837. }
  4838. /**
  4839. * @author Kieran Hogg
  4840. * @param int $seconds. Number of seconds
  4841. * @returns string. Readable time in seconds
  4842. */
  4843. function exact_seconds($seconds)
  4844. {
  4845. $days = floor($seconds / (24 * 60 * 60));
  4846. $seconds -= $days * (24 * 60 * 60);
  4847. $hours = floor($seconds / (60 * 60));
  4848. $seconds -= $hours * (60 * 60);
  4849. $minutes = floor($seconds / 60);
  4850. $seconds -= $minutes * 60;
  4851. $string = "";
  4852. if ($days != 0) $string .= "{$days} {$GLOBALS['strDays']}, ";
  4853. if ($hours != 0) $string .= "{$hours} {$GLOBALS['strHours']}, ";
  4854. if ($minutes != 0) $string .= "{$minutes} {$GLOBALS['strMinutes']}, ";
  4855. $string .= "{$seconds} {$GLOBALS['strSeconds']}";
  4856. return $string;
  4857. }
  4858. /**
  4859. * Shows errors from a form, if any
  4860. * @author Kieran Hogg
  4861. * @returns string. HTML of the form errors stored in the users session
  4862. */
  4863. function show_form_errors($formname)
  4864. {
  4865. if ($_SESSION['formerrors'][$formname])
  4866. {
  4867. foreach ($_SESSION['formerrors'][$formname] as $error)
  4868. {
  4869. $html .= "<p class='error'>$error</p>";
  4870. }
  4871. }
  4872. return $html;
  4873. }
  4874. /**
  4875. * Cleans form errors
  4876. * @author Kieran Hogg
  4877. * @returns nothing
  4878. */
  4879. function clear_form_errors($formname)
  4880. {
  4881. unset($_SESSION['formerrors'][$formname]);
  4882. }
  4883. /**
  4884. * Cleans form data
  4885. * @author Kieran Hogg
  4886. * @returns nothing
  4887. */
  4888. function clear_form_data($formname)
  4889. {
  4890. unset($_SESSION['formdata'][$formname]);
  4891. }
  4892. /**
  4893. * Adjust a timezoned date/time to UTC
  4894. * @author Ivan Lucas
  4895. * @param int UNIX timestamp. Uses 'now' if ommitted
  4896. * @returns int UNIX timestamp (in UTC)
  4897. */
  4898. function utc_time($time = '')
  4899. {
  4900. if ($time == '') $time = $GLOBALS['now'];
  4901. $tz = strftime('%z', $time);
  4902. $tzmins = (substr($tz, -4, 2) * 60) + substr($tz, -2, 2);
  4903. $tzsecs = $tzmins * 60; // convert to seconds
  4904. if (substr($tz, 0, 1) == '+') $time -= $tzsecs;
  4905. else $time += $tzsecs;
  4906. return $time;
  4907. }
  4908. /**
  4909. * Returns a localised and translated date
  4910. * @author Ivan Lucas
  4911. * @param string $format. date() format
  4912. * @param int $date. UNIX timestamp. Uses 'now' if ommitted
  4913. * @param bool $utc bool. Is the timestamp being passed as UTC or system time
  4914. TRUE = passed as UTC
  4915. FALSE = passed as system time
  4916. * @returns string. An internationised date/time string
  4917. * @todo th/st and am/pm maybe?
  4918. */
  4919. function ldate($format, $date = '', $utc = TRUE)
  4920. {
  4921. if ($date == '') $date = $GLOBALS['now'];
  4922. if ($_SESSION['utcoffset'] != '')
  4923. {
  4924. if (!$utc)
  4925. {
  4926. // Adjust the date back to UTC
  4927. $date = utc_time($date);
  4928. }
  4929. // Adjust the display time to the users local timezone
  4930. $useroffsetsec = $_SESSION['utcoffset'] * 60;
  4931. $date += $useroffsetsec;
  4932. }
  4933. $datestring = gmdate($format, $date);
  4934. // Internationalise date endings (e.g. st)
  4935. if (strpos($format, 'S') !== FALSE)
  4936. {
  4937. $endings = array('st', 'nd', 'rd', 'th');
  4938. $i18nendings = array($GLOBALS['strst'], $GLOBALS['strnd'],
  4939. $GLOBALS['strrd'], $GLOBALS['strth']);
  4940. $datestring = str_replace($endings, $i18nendings, $datestring);
  4941. }
  4942. // Internationalise full day names
  4943. if (strpos($format, 'l') !== FALSE)
  4944. {
  4945. $days = array('Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday');
  4946. $i18ndays = array($GLOBALS['strMonday'], $GLOBALS['strTuesday'], $GLOBALS['strWednesday'],
  4947. $GLOBALS['strThursday'], $GLOBALS['strFriday'], $GLOBALS['strSaturday'], $GLOBALS['strSunday']);
  4948. $datestring = str_replace($days, $i18ndays, $datestring);
  4949. }
  4950. // Internationalise abbreviated day names
  4951. if (strpos($format, 'D') !== FALSE)
  4952. {
  4953. $days = array('Mon','Tue','Wed','Thu','Fri','Sat','Sun');
  4954. $i18ndays = array($GLOBALS['strMon'], $GLOBALS['strTue'], $GLOBALS['strWed'],
  4955. $GLOBALS['strThu'], $GLOBALS['strFri'], $GLOBALS['strSat'], $GLOBALS['strSun']);
  4956. $datestring = str_replace($days, $i18ndays, $datestring);
  4957. }
  4958. // Internationalise full month names
  4959. if (strpos($format, 'F') !== FALSE)
  4960. {
  4961. $months = array('January','February','March','April','May','June','July','August','September','October','November','December');
  4962. $i18nmonths = array($GLOBALS['strJanuary'], $GLOBALS['strFebruary'], $GLOBALS['strMarch'],
  4963. $GLOBALS['strApril'], $GLOBALS['strMay'], $GLOBALS['strJune'], $GLOBALS['strJuly'],
  4964. $GLOBALS['strAugust'], $GLOBALS['strSeptember'], $GLOBALS['strOctober'],
  4965. $GLOBALS['strNovember'], $GLOBALS['strDecember']);
  4966. $datestring = str_replace($months, $i18nmonths, $datestring);
  4967. }
  4968. // Internationalise short month names
  4969. if (strpos($format, 'M') !== FALSE)
  4970. {
  4971. $months = array('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
  4972. $i18nmonths = array($GLOBALS['strJanAbbr'], $GLOBALS['strFebAbbr'], $GLOBALS['strMarAbbr'],
  4973. $GLOBALS['strAprAbbr'], $GLOBALS['strMayAbbr'], $GLOBALS['strJunAbbr'], $GLOBALS['strJulAbbr'],
  4974. $GLOBALS['strAugAbbr'], $GLOBALS['strSepAbbr'], $GLOBALS['strOctAbbr'],
  4975. $GLOBALS['strNovAbbr'], $GLOBALS['strDecAbbr']);
  4976. $datestring = str_replace($months, $i18nmonths, $datestring);
  4977. }
  4978. // Internationalise am/pm
  4979. if (strpos($format, 'a') !== FALSE)
  4980. {
  4981. $months = array('am','pm');
  4982. $i18nmonths = array($GLOBALS['strAM'], $GLOBALS['strPM']);
  4983. $datestring = str_replace($months, $i18nmonths, $datestring);
  4984. }
  4985. return $datestring;
  4986. }
  4987. /**
  4988. * Returns an array of open activities/timed tasks for an incident
  4989. * @author Paul Heaney
  4990. * @param int $incidentid. Incident ID you want
  4991. * @returns array - with the task id
  4992. */
  4993. function open_activities_for_incident($incientid)
  4994. {
  4995. global $dbLinks, $dbLinkTypes, $dbTasks;
  4996. // Running Activities
  4997. $sql = "SELECT DISTINCT origcolref, linkcolref ";
  4998. $sql .= "FROM `{$dbLinks}` AS l, `{$dbLinkTypes}` AS lt ";
  4999. $sql .= "WHERE l.linktype=4 ";
  5000. $sql .= "AND linkcolref={$incientid} ";
  5001. $sql .= "AND direction='left'";
  5002. $result = mysql_query($sql);
  5003. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  5004. if (mysql_num_rows($result) > 0)
  5005. {
  5006. //get list of tasks
  5007. $sql = "SELECT * FROM `{$dbTasks}` WHERE enddate IS NULL ";
  5008. while ($tasks = mysql_fetch_object($result))
  5009. {
  5010. if (empty($orSQL)) $orSQL = "(";
  5011. else $orSQL .= " OR ";
  5012. $orSQL .= "id={$tasks->origcolref} ";
  5013. }
  5014. if (!empty($orSQL))
  5015. {
  5016. $sql .= "AND {$orSQL})";
  5017. }
  5018. $result = mysql_query($sql);
  5019. // $num = mysql_num_rows($result);
  5020. while ($obj = mysql_fetch_object($result))
  5021. {
  5022. $num[] = $obj->id;
  5023. }
  5024. }
  5025. else
  5026. {
  5027. $num = null;
  5028. }
  5029. return $num;
  5030. }
  5031. /**
  5032. * Returns the number of open activities/timed tasks for a site
  5033. * @author Paul Heaney
  5034. * @param int $siteid. Site ID you want
  5035. * @returns int. Number of open activities for the site (0 if non)
  5036. */
  5037. function open_activities_for_site($siteid)
  5038. {
  5039. global $dbIncidents, $dbContacts;
  5040. $openactivites = 0;
  5041. if (!empty($siteid) AND $siteid != 0)
  5042. {
  5043. $sql = "SELECT i.id FROM `{$dbIncidents}` AS i, `{$dbContacts}` AS c ";
  5044. $sql .= "WHERE i.contact = c.id AND ";
  5045. $sql .= "c.siteid = {$siteid} AND ";
  5046. $sql .= "(i.status != 2 AND i.status != 7)";
  5047. $result = mysql_query($sql);
  5048. while ($obj = mysql_fetch_object($result))
  5049. {
  5050. $openactivites += count(open_activities_for_incident($obj->id));
  5051. }
  5052. }
  5053. return $openactivites;
  5054. }
  5055. /**
  5056. * Finds out which scheduled tasks should be run right now
  5057. * @author Ivan Lucas, Paul Heaney
  5058. * @returns array
  5059. */
  5060. function schedule_actions_due()
  5061. {
  5062. global $now;
  5063. global $dbScheduler;
  5064. $actions = FALSE;
  5065. $sql = "SELECT * FROM `{$dbScheduler}` WHERE status = 'enabled' AND type = 'interval' ";
  5066. $sql .= "AND UNIX_TIMESTAMP(start) <= $now AND (UNIX_TIMESTAMP(end) >= $now OR UNIX_TIMESTAMP(end) = 0) ";
  5067. $sql .= "AND IF(UNIX_TIMESTAMP(lastran) > 0, UNIX_TIMESTAMP(lastran) + `interval` <= $now, 1=1) ";
  5068. $sql .= "AND IF(laststarted > 0, laststarted <= lastran, 1=1)";
  5069. $result = mysql_query($sql);
  5070. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  5071. if (mysql_num_rows($result) > 0)
  5072. {
  5073. while ($action = mysql_fetch_object($result))
  5074. {
  5075. $actions[$action->action] = $actions->params;
  5076. }
  5077. }
  5078. // Month
  5079. $sql = "SELECT * FROM `{$dbScheduler}` WHERE status = 'enabled' AND type = 'date' ";
  5080. $sql .= "AND UNIX_TIMESTAMP(start) <= $now AND (UNIX_TIMESTAMP(end) >= $now OR UNIX_TIMESTAMP(end) = 0) ";
  5081. $sql .= "AND ((date_type = 'month' AND (DAYOFMONTH(CURDATE()) > date_offset OR (DAYOFMONTH(CURDATE()) = date_offset AND CURTIME() >= date_time)) ";
  5082. $sql .= "AND DATE_FORMAT(CURDATE(), '%Y-%m') != DATE_FORMAT(lastran, '%Y-%m') ) ) "; // not run this month
  5083. $sql .= "AND IF(laststarted > 0, laststarted <= lastran, 1=1)";
  5084. $result = mysql_query($sql);
  5085. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  5086. if (mysql_num_rows($result) > 0)
  5087. {
  5088. while ($action = mysql_fetch_object($result))
  5089. {
  5090. $actions[$action->action] = $actions->params;
  5091. }
  5092. }
  5093. // Year TODO CHECK
  5094. $sql = "SELECT * FROM `{$dbScheduler}` WHERE status = 'enabled' ";
  5095. $sql .= "AND type = 'date' AND UNIX_TIMESTAMP(start) <= $now ";
  5096. $sql .= "AND (UNIX_TIMESTAMP(end) >= $now OR UNIX_TIMESTAMP(end) = 0) ";
  5097. $sql .= "AND ((date_type = 'year' AND (DAYOFYEAR(CURDATE()) > date_offset ";
  5098. $sql .= "OR (DAYOFYEAR(CURDATE()) = date_offset AND CURTIME() >= date_time)) ";
  5099. $sql .= "AND DATE_FORMAT(CURDATE(), '%Y') != DATE_FORMAT(lastran, '%Y') ) ) "; // not run this year
  5100. $sql .= "AND IF(laststarted > 0, laststarted <= lastran, 1=1)";
  5101. $result = mysql_query($sql);
  5102. if (mysql_error()) trigger_error(mysql_error(),E_USER_WARNING);
  5103. if (mysql_num_rows($result) > 0)
  5104. {
  5105. while ($action = mysql_fetch_object($result))
  5106. {
  5107. $actions[$action->action] = $actions->params;
  5108. }
  5109. }
  5110. return $actions;
  5111. }
  5112. /**
  5113. * Marks a schedule action as started
  5114. * @author Paul Heaney
  5115. * @param string $action. Name of scheduled action
  5116. * @return boolean Success of update
  5117. */
  5118. function schedule_action_started($action)
  5119. {
  5120. global $now;
  5121. $nowdate = date('Y-m-d H:i:s', $now);
  5122. $sql = "UPDATE `{$GLOBALS['dbScheduler']}` SET laststarted = '$nowdate' ";
  5123. $sql .= "WHERE action = '{$action}'";
  5124. mysql_query($sql);
  5125. if (mysql_error())
  5126. {
  5127. trigger_error(mysql_error(),E_USER_ERROR);
  5128. return FALSE;
  5129. }
  5130. if (mysql_affected_rows() > 0) return TRUE;
  5131. else return FALSE;
  5132. }
  5133. /**
  5134. * Mark a schedule action as done
  5135. * @author Ivan Lucas
  5136. * @param string $doneaction. Name of scheduled action
  5137. * @param bool $success. Was the run successful, TRUE = Yes, FALSE = No
  5138. */
  5139. function schedule_action_done($doneaction, $success = TRUE)
  5140. {
  5141. global $now;
  5142. global $dbScheduler;
  5143. if ($success != TRUE)
  5144. {
  5145. trigger('TRIGGER_SCHEDULER_TASK_FAILED', array('schedulertask' => $doneaction));
  5146. }
  5147. $nowdate = date('Y-m-d H:i:s', $now);
  5148. $sql = "UPDATE `{$dbScheduler}` SET lastran = '$nowdate' ";
  5149. if ($success == FALSE) $sql .= ", success=0, status='disabled' ";
  5150. else $sql .= ", success=1 ";
  5151. $sql .= "WHERE action = '{$doneaction}'";
  5152. mysql_query($sql);
  5153. if (mysql_error())
  5154. {
  5155. trigger_error(mysql_error(),E_USER_ERROR);
  5156. return FALSE;
  5157. }
  5158. if (mysql_affected_rows() > 0) return TRUE;
  5159. else return FALSE;
  5160. }
  5161. /**
  5162. * Return an array of contacts allowed to use this contract
  5163. * @author Kieran Hogg
  5164. * @param int $maintid - ID of the contract
  5165. * @return array of supported contacts, NULL if none
  5166. **/
  5167. function supported_contacts($maintid)
  5168. {
  5169. global $dbSupportContacts, $dbContacts;
  5170. $sql = "SELECT c.forenames, c.surname, sc.contactid AS contactid ";
  5171. $sql .= "FROM `{$dbSupportContacts}` AS sc, `{$dbContacts}` AS c ";
  5172. $sql .= "WHERE sc.contactid=c.id AND sc.maintenanceid='{$maintid}' ";
  5173. $sql .= "ORDER BY c.surname, c.forenames ";
  5174. $result = mysql_query($sql);
  5175. if (mysql_error()) trigger_error("MySQL Query Error ".mysql_error(), E_USER_WARNING);
  5176. if (!empty($result))
  5177. {
  5178. while ($row = mysql_fetch_object($result))
  5179. {
  5180. $returnarray[] = $row->contactid;
  5181. }
  5182. return $returnarray;
  5183. }
  5184. else return NULL;
  5185. }
  5186. /**
  5187. * Return an array of contracts which the contact is an admin contact for
  5188. * @author Kieran Hogg
  5189. * @param int $maintid - ID of the contract
  5190. * @param int $siteid - The ID of the site
  5191. * @return array of contract ID's for which the given contactid is an admin contact, NULL if none
  5192. */
  5193. function admin_contact_contracts($contactid, $siteid)
  5194. {
  5195. $sql = "SELECT DISTINCT m.id ";
  5196. $sql .= "FROM `{$GLOBALS['dbMaintenance']}` AS m ";
  5197. $sql .= "WHERE m.admincontact={$contactid} ";
  5198. $sql .= "AND m.site={$siteid} ";
  5199. $result = mysql_query($sql);
  5200. if (mysql_error()) trigger_error("MySQL Query Error ".mysql_error(), E_USER_WARNING);
  5201. if ($result)
  5202. {
  5203. while ($row = mysql_fetch_object($result))
  5204. {
  5205. $contractsarray[] = $row->id;
  5206. }
  5207. }
  5208. return $contractsarray;
  5209. }
  5210. /**
  5211. * Return an array of contracts which the contact is an named contact for
  5212. * @author Kieran Hogg
  5213. * @param int $maintid - ID of the contract
  5214. * @return array of supported contracts, NULL if none
  5215. */
  5216. function contact_contracts($contactid, $siteid, $checkvisible = TRUE)
  5217. {
  5218. $sql = "SELECT DISTINCT m.id AS id
  5219. FROM `{$GLOBALS['dbMaintenance']}` AS m,
  5220. `{$GLOBALS['dbContacts']}` AS c,
  5221. `{$GLOBALS['dbSupportContacts']}` AS sc
  5222. WHERE m.site={$siteid}
  5223. AND sc.maintenanceid=m.id
  5224. AND sc.contactid=c.id ";
  5225. if ($checkvisible)
  5226. {
  5227. $sql .= "AND m.var_incident_visible_contacts = 'yes'";
  5228. }
  5229. if ($result = mysql_query($sql))
  5230. {
  5231. while ($row = mysql_fetch_object($result))
  5232. {
  5233. $contractsarray[] = $row->id;
  5234. }
  5235. }
  5236. return $contractsarray;
  5237. }
  5238. /**
  5239. * Return an array of contracts which non-contract contacts can see incidents
  5240. * @author Kieran Hogg
  5241. * @param int $maintid - ID of the contract
  5242. * @return array of supported contracts, NULL if none
  5243. **/
  5244. function all_contact_contracts($contactid, $siteid)
  5245. {
  5246. $sql = "SELECT DISTINCT m.id AS id
  5247. FROM `{$GLOBALS['dbMaintenance']}` AS m,
  5248. WHERE m.site={$siteid}
  5249. AND m.var_incident_visible_all = 'yes'";
  5250. if ($result = mysql_query($sql))
  5251. {
  5252. while ($row = mysql_fetch_object($result))
  5253. {
  5254. $contractsarray[] = $row->id;
  5255. }
  5256. }
  5257. return $contractsarray;
  5258. }
  5259. /**
  5260. * Checks is a given username is unique
  5261. * @author Kieran Hogg
  5262. * @param string $username - username
  5263. * @return bool TRUE if valid, FALSE if not
  5264. */
  5265. function valid_username($username)
  5266. {
  5267. $username = cleanvar($username);
  5268. $valid = TRUE;
  5269. $tables = array('dbUsers', 'dbContacts');
  5270. foreach ($tables AS $table)
  5271. {
  5272. $sql = "SELECT username FROM `{$GLOBALS[$table]}` WHERE username='{$username}'";
  5273. if ($result = mysql_query($sql) AND mysql_num_rows($result) != 0)
  5274. {
  5275. $valid = FALSE;
  5276. }
  5277. }
  5278. return $valid;
  5279. }
  5280. /**
  5281. * Update the current session id with a newly generated one
  5282. * @author Ivan Lucas
  5283. * @note Wrap the php function for different versions of php
  5284. */
  5285. function session_regenerate()
  5286. {
  5287. if (function_exists('session_regenerate_id'))
  5288. {
  5289. if (!version_compare(phpversion(),"5.1.0",">=")) session_regenerate_id(FALSE);
  5290. else session_regenerate_id();
  5291. }
  5292. }
  5293. /**
  5294. * Finds the software associated with a contract
  5295. * @author Ivan Lucas
  5296. * @note Wrap the php function for different versions of php
  5297. */
  5298. function contract_software()
  5299. {
  5300. $contract = intval($contract);
  5301. $sql = "SELECT s.id
  5302. FROM `{$GLOBALS['dbMaintenance']}` AS m,
  5303. `{$GLOBALS['dbProducts']}` AS p,
  5304. `{$GLOBALS['dbSoftwareProducts']}` AS sp,
  5305. `{$GLOBALS['dbSoftware']}` AS s
  5306. WHERE m.product=p.id
  5307. AND p.id=sp.productid
  5308. AND sp.softwareid=s.id ";
  5309. $sql .= "AND (1=0 ";
  5310. if (is_array($_SESSION['contracts']))
  5311. {
  5312. foreach ($_SESSION['contracts'] AS $contract)
  5313. {
  5314. $sql .= "OR m.id={$contract} ";
  5315. }
  5316. }
  5317. $sql .= ")";
  5318. if ($result = mysql_query($sql))
  5319. {
  5320. while ($row = mysql_fetch_object($result))
  5321. {
  5322. $softwarearray[] = $row->id;
  5323. }
  5324. }
  5325. return $softwarearray;
  5326. }
  5327. /**
  5328. * HTML for an ajax help link
  5329. * @author Ivan Lucas
  5330. * @param string $context. The base filename of the popup help file in
  5331. help/en-GB/ (without the .txt extension)
  5332. * @return string HTML
  5333. */
  5334. function help_link($context)
  5335. {
  5336. global $strHelpChar;
  5337. $html = "<span class='helplink'>[<a href='#' tabindex='-1' onmouseover=\"";
  5338. $html .= "contexthelp(this, '$context'";
  5339. if ($_SESSION['portalauth'] == TRUE) $html .= ",'portal'";
  5340. else $html .= ",'standard'";
  5341. $html .= ");return false;\">{$strHelpChar}<span>";
  5342. $html .= "</span></a>]</span>";
  5343. return $html;
  5344. }
  5345. /**
  5346. * Function to return an user error message when a file fails to upload
  5347. * @author Paul Heaney
  5348. * @param errorcode The error code from $_FILES['file']['error']
  5349. * @param name The file name which was uploaded from $_FILES['file']['name']
  5350. * @return String containing the error message (in HTML)
  5351. */
  5352. function get_file_upload_error_message($errorcode, $name)
  5353. {
  5354. $str = "<div class='detailinfo'>\n";
  5355. $str .= "An error occurred while uploading <strong>{$_FILES['attachment']['name']}</strong>";
  5356. $str .= "<p class='error'>";
  5357. switch ($errorcode)
  5358. {
  5359. case UPLOAD_ERR_INI_SIZE: $str .= "The file exceded the maximum size set in PHP"; break;
  5360. case UPLOAD_ERR_FORM_SIZE: $str .= "The uploaded file was too large"; break;
  5361. case UPLOAD_ERR_PARTIAL: $str .= "The file was only partially uploaded"; break;
  5362. case UPLOAD_ERR_NO_FILE: $str .= "No file was uploaded"; break;
  5363. case UPLOAD_ERR_NO_TMP_DIR: $str .= "Temporary folder is missing"; break;
  5364. default: $str .= "An unknown file upload error occurred"; break;
  5365. }
  5366. $str .= "</p>";
  5367. $str .= "</div>";
  5368. return $str;
  5369. }
  5370. /**
  5371. * Function to produce a user readable file size i.e 2048 bytes 1KB etc
  5372. * @author Paul Heaney
  5373. * @param filesize - filesize in bytes
  5374. * @return String filesize in readable format
  5375. */
  5376. function readable_file_size($filesize)
  5377. {
  5378. global $strBytes, $strKBytes, $strMBytes, $strGBytes, $strTBytes;
  5379. $j = 0;
  5380. $ext = array($strBytes, $strKBytes, $strMBytes, $strGBytes, $strTBytes);
  5381. while ($filesize >= pow(1024,$j))
  5382. {
  5383. ++$j;
  5384. }
  5385. $filemax = round($filesize / pow(1024,$j-1) * 100) / 100 . ' ' . $ext[$j-1];
  5386. return $filemax;
  5387. }
  5388. /**
  5389. * Return the html of contract detatils
  5390. * @author Kieran Hogg
  5391. * @param int $maintid - ID of the contract
  5392. * @param string $mode. 'internal' or 'external'
  5393. * @return array of supported contracts, NULL if none
  5394. * @todo FIXME not quite generic enough for a function ?
  5395. */
  5396. function contract_details($id, $mode='internal')
  5397. {
  5398. global $CONFIG, $iconset, $dbMaintenance, $dbSites, $dbResellers, $dbLicenceTypes, $now;
  5399. $sql = "SELECT m.*, m.notes AS maintnotes, s.name AS sitename, ";
  5400. $sql .= "r.name AS resellername, lt.name AS licensetypename ";
  5401. $sql .= "FROM `{$dbMaintenance}` AS m, `{$dbSites}` AS s, ";
  5402. $sql .= "`{$dbResellers}` AS r, `{$dbLicenceTypes}` AS lt ";
  5403. $sql .= "WHERE s.id = m.site ";
  5404. $sql .= "AND m.id='{$id}' ";
  5405. $sql .= "AND m.reseller = r.id ";
  5406. $sql .= "AND (m.licence_type IS NULL OR m.licence_type = lt.id) ";
  5407. if ($mode == 'external') $sql .= "AND m.site = '{$_SESSION['siteid']}'";
  5408. $maintresult = mysql_query($sql);
  5409. if (mysql_error()) trigger_error("MySQL Query Error ".mysql_error(), E_USER_WARNING);
  5410. $maint = mysql_fetch_object($maintresult);
  5411. $html = "<table align='center' class='vertical'>";
  5412. $html .= "<tr><th>{$GLOBALS['strContract']} {$GLOBALS['strID']}:</th>";
  5413. $html .= "<td><h3>".icon('contract', 32)." ";
  5414. $html .= "{$maint->id}</h3></td></tr>";
  5415. $html .= "<tr><th>{$GLOBALS['strStatus']}:</th><td>";
  5416. if ($maint->term == 'yes')
  5417. {
  5418. $html .= "<strong>{$GLOBALS['strTerminated']}</strong>";
  5419. }
  5420. else
  5421. {
  5422. $html .= $GLOBALS['strActive'];
  5423. }
  5424. if ($maint->expirydate < $now AND $maint->expirydate != '-1')
  5425. {
  5426. $html .= "<span class='expired'>, {$GLOBALS['strExpired']}</span>";
  5427. }
  5428. $html .= "</td></tr>\n";
  5429. $html .= "<tr><th>{$GLOBALS['strSite']}:</th>";
  5430. if ($mode == 'internal')
  5431. {
  5432. $html .= "<td><a href=\"site_details.php?id=".$maint->site."\">".$maint->sitename."</a></td></tr>";
  5433. }
  5434. else
  5435. {
  5436. $html .= "<td><a href=\"sitedetails.php\">".$maint->sitename."</a></td></tr>";
  5437. }
  5438. $html .= "<tr><th>{$GLOBALS['strAdminContact']}:</th>";
  5439. if ($mode == 'internal')
  5440. {
  5441. $html .= "<td><a href=\"contact_details.php?id=";
  5442. $html .= "{$maint->admincontact}\">";
  5443. $html .= contact_realname($maint->admincontact)."</a></td></tr>";
  5444. }
  5445. else
  5446. {
  5447. $html .= "<td><a href='contactdetails.php?id={$maint->admincontact}'>";
  5448. $html .= contact_realname($maint->admincontact)."</a></td></tr>";
  5449. }
  5450. $html .= "<tr><th>{$GLOBALS['strReseller']}:</th><td>";
  5451. if (empty($maint->resellername))
  5452. {
  5453. $html .= $GLOBALS['strNoReseller'];
  5454. }
  5455. else
  5456. {
  5457. $html .= $maint->resellername;
  5458. }
  5459. $html .= "</td></tr>";
  5460. $html .= "<tr><th>{$GLOBALS['strProduct']}:</th><td>".product_name($maint->product)."</td></tr>";
  5461. $html .= "<tr><th>{$GLOBALS['strIncidents']}:</th>";
  5462. $html .= "<td>";
  5463. $incidents_remaining = $maint->incident_quantity - $maint->incidents_used;
  5464. if ($maint->incident_quantity == 0)
  5465. {
  5466. $quantity = $GLOBALS['strUnlimited'];
  5467. }
  5468. else
  5469. {
  5470. $quantity = $maint->incident_quantity;
  5471. }
  5472. $html .= sprintf($GLOBALS['strUsedNofN'], $maint->incidents_used, $quantity);
  5473. if ($maint->incidents_used >= $maint->incident_quantity AND
  5474. $maint->incident_quantity != 0)
  5475. {
  5476. $html .= " ({$GLOBALS['strZeroRemaining']})";
  5477. }
  5478. $html .= "</td></tr>";
  5479. if ($maint->licence_quantity != '0')
  5480. {
  5481. $html .= "<tr><th>{$GLOBALS['strLicense']}:</th>";
  5482. $html .= "<td>{$maint->licence_quantity} {$maint->licensetypename}</td></tr>\n";
  5483. }
  5484. $html .= "<tr><th>{$GLOBALS['strServiceLevel']}:</th><td>".servicelevel_name($maint->servicelevelid)."</td></tr>";
  5485. $html .= "<tr><th>{$GLOBALS['strExpiryDate']}:</th><td>";
  5486. if ($maint->expirydate == '-1')
  5487. {
  5488. $html .= "{$GLOBALS['strUnlimited']}";
  5489. }
  5490. else
  5491. {
  5492. $html .= ldate($CONFIG['dateformat_date'], $maint->expirydate);
  5493. }
  5494. $html .= "</td></tr>";
  5495. if ($mode == 'internal')
  5496. {
  5497. $timed = db_read_column('timed', $GLOBALS['dbServiceLevels'], $maint->servicelevelid);
  5498. if ($timed == 'yes') $timed = TRUE;
  5499. else $timed = FALSE;
  5500. $html .= "<tr><th>{$GLOBALS['strService']}</th><td>";
  5501. $html .= contract_service_table($id, $timed);
  5502. $html .= "</td></tr>\n";
  5503. if ($timed)
  5504. {
  5505. $html .= "<tr><th>{$GLOBALS['strBalance']}</th><td>{$CONFIG['currency_symbol']}".number_format(get_contract_balance($id, TRUE, TRUE), 2);
  5506. $multiplier = get_billable_multiplier(strtolower(date('D', $now)), date('G', $now));
  5507. $html .= " (&cong;".contract_unit_balance($id, TRUE, TRUE)." units)";
  5508. $html .= "</td></tr>";
  5509. }
  5510. }
  5511. if ($maint->maintnotes != '' AND $mode == 'internal')
  5512. {
  5513. $html .= "<tr><th>{$GLOBALS['strNotes']}:</th><td>{$maint->maintnotes}</td></tr>";
  5514. }
  5515. $html .= "</table>";
  5516. if ($mode == 'internal')
  5517. {
  5518. $html .= "<p align='center'>";
  5519. $html .= "<a href=\"contract_edit.php?action=edit&amp;maintid=$id\">{$GLOBALS['strEditContract']}</a> | ";
  5520. $html .= "<a href='contract_add_service.php?contractid={$id}'>{$GLOBALS['strAddService']}</a></p>";
  5521. }
  5522. $html .= "<h3>{$GLOBALS['strContacts']}</h3>";
  5523. if (mysql_num_rows($maintresult) > 0)
  5524. {
  5525. if ($maint->allcontactssupported == 'yes')
  5526. {
  5527. $html .= "<p class='info'>{$GLOBALS['strAllSiteContactsSupported']}</p>";
  5528. }
  5529. else
  5530. {
  5531. $allowedcontacts = $maint->supportedcontacts;
  5532. $supportedcontacts = supported_contacts($id);
  5533. $numberofcontacts = 0;
  5534. $numberofcontacts = sizeof($supportedcontacts);
  5535. if ($allowedcontacts == 0)
  5536. {
  5537. $allowedcontacts = $GLOBALS['strUnlimited'];
  5538. }
  5539. $html .= "<table align='center'>";
  5540. $supportcount = 1;
  5541. if ($numberofcontacts > 0)
  5542. {
  5543. foreach ($supportedcontacts AS $contact)
  5544. {
  5545. $html .= "<tr><th>{$GLOBALS['strContact']} #{$supportcount}:</th>";
  5546. $html .= "<td>".icon('contact', 16)." ";
  5547. if ($mode == 'internal')
  5548. {
  5549. $html .= "<a href=\"contact_details.php?";
  5550. }
  5551. else
  5552. {
  5553. $html .= "<a href=\"contactdetails.php?";
  5554. }
  5555. $html .= "id={$contact}\">".contact_realname($contact)."</a>, ";
  5556. $html .= contact_site($contact). "</td>";
  5557. if ($mode == 'internal')
  5558. {
  5559. $html .= "<td><a href=\"contract_delete_contact.php?contactid=".$contact."&amp;maintid=$id&amp;context=maintenance\">{$GLOBALS['strRemove']}</a></td></tr>\n";
  5560. }
  5561. else
  5562. {
  5563. $html .= "<td><a href=\"{$_SERVER['PHP_SELF']}?id={$id}&amp;contactid=".$contact."&amp;action=remove\">{$GLOBALS['strRemove']}</a></td></tr>\n";
  5564. }
  5565. $supportcount++;
  5566. }
  5567. $html .= "</table>";
  5568. }
  5569. else
  5570. {
  5571. $html .= "<p class='info'>{$GLOBALS['strNoRecords']}<p>";
  5572. }
  5573. }
  5574. if ($maint->allcontactssupported != 'yes')
  5575. {
  5576. $html .= "<p align='center'>";
  5577. $html .= sprintf($GLOBALS['strUsedNofN'],
  5578. "<strong>".$numberofcontacts."</strong>",
  5579. "<strong>".$allowedcontacts."</strong>");
  5580. $html .= "</p>";
  5581. if ($numberofcontacts < $allowedcontacts OR $allowedcontacts == 0 AND $mode == 'internal')
  5582. {
  5583. $html .= "<p align='center'><a href='contract_add_contact.php?maintid={$id}&amp;siteid={$maint->site}&amp;context=maintenance'>";
  5584. $html .= "{$GLOBALS['strAddContact']}</a></p>";
  5585. }
  5586. else
  5587. {
  5588. $html .= "<h3>{$GLOBALS['strAddContact']}</h3>";
  5589. $html .= "<form action='{$_SERVER['PHP_SELF']}?id={$id}&amp;action=";
  5590. $html .= "add' method='post' >";
  5591. $html .= "<p align='center'>{$GLOBLAS['strAddNewSupportedContact']} ";
  5592. $html .= contact_site_drop_down('contactid',
  5593. 'contactid',
  5594. maintenance_siteid($id),
  5595. supported_contacts($id));
  5596. $html .= help_link('NewSupportedContact');
  5597. $html .= " <input type='submit' value='{$GLOBALS['strAdd']}' /></p></form>";
  5598. }
  5599. if ($mode == 'external')
  5600. {
  5601. $html .= "<p align='center'><a href='addcontact.php'>";
  5602. $html .= "{$GLOBALS['strAddNewSiteContact']}</a></p>";
  5603. }
  5604. }
  5605. $html .= "<br />";
  5606. $html .= "<h3>{$GLOBALS['strSkillsSupportedUnderContract']}:</h3>";
  5607. // supported software
  5608. $sql = "SELECT * FROM `{$GLOBALS[dbSoftwareProducts]}` AS sp, `{$GLOBALS[dbSoftware]}` AS s ";
  5609. $sql .= "WHERE sp.softwareid = s.id AND productid='{$maint->product}' ";
  5610. $result = mysql_query($sql);
  5611. if (mysql_error()) trigger_error("MySQL Query Error ".mysql_error(), E_USER_WARNING);
  5612. if (mysql_num_rows($result)>0)
  5613. {
  5614. $html .="<table align='center'>";
  5615. while ($software = mysql_fetch_object($result))
  5616. {
  5617. $software->lifetime_end = mysql2date($software->lifetime_end);
  5618. $html .= "<tr><td> ".icon('skill', 16)." ";
  5619. if ($software->lifetime_end > 0 AND $software->lifetime_end < $now)
  5620. {
  5621. $html .= "<span class='deleted'>";
  5622. }
  5623. $html .= $software->name;
  5624. if ($software->lifetime_end > 0 AND $software->lifetime_end < $now)
  5625. {
  5626. $html .= "</span>";
  5627. }
  5628. $html .= "</td></tr>\n";
  5629. }
  5630. $html .= "</table>\n";
  5631. }
  5632. else
  5633. {
  5634. $html .= "<p align='center'>{$GLOBALS['strNone']} / {$GLOBALS['strUnknown']}<p>";
  5635. }
  5636. }
  5637. else $html = "<p align='center'>{$GLOBALS['strNothingToDisplay']}</p>";
  5638. return $html;
  5639. }
  5640. /**
  5641. * Uploads a file
  5642. * @author Kieran Hogg
  5643. * @param mixed $file file to upload
  5644. * @param int $incidentd
  5645. * @return string path of file
  5646. * @todo FIXME this function doesn't seem to make use of $updateid and is never called, is it still used?'
  5647. */
  5648. function upload_file($file, $incidentid, $updateid, $type='public')
  5649. {
  5650. global $CONFIG, $now;
  5651. $att_max_filesize = return_bytes($CONFIG['upload_max_filesize']);
  5652. $incident_attachment_fspath = $CONFIG['attachment_fspath'] . $id; //FIXME $id never declared
  5653. if ($file['name'] != '')
  5654. {
  5655. // try to figure out what delimeter is being used (for windows or unix)...
  5656. //.... // $delim = (strstr($filesarray[$c],"/")) ? "/" : "\\";
  5657. $delim = (strstr($file['tmp_name'],"/")) ? "/" : "\\";
  5658. // make incident attachment dir if it doesn't exist
  5659. $umask = umask(0000);
  5660. if (!file_exists($CONFIG['attachment_fspath'] . "$id"))
  5661. {
  5662. $mk = @mkdir($CONFIG['attachment_fspath'] ."$id", 0770);
  5663. if (!$mk) trigger_error("Failed creating incident attachment directory: {$incident_attachment_fspath }{$id}", E_USER_WARNING);
  5664. }
  5665. $mk = @mkdir($CONFIG['attachment_fspath'] .$id . "{$delim}{$now}", 0770);
  5666. if (!$mk) trigger_error("Failed creating incident attachment (timestamp) directory: {$incident_attachment_fspath} {$id} {$delim}{$now}", E_USER_WARNING);
  5667. umask($umask);
  5668. $returnpath = $id.$delim.$now.$delim.$file['name'];
  5669. $filepath = $incident_attachment_fspath.$delim.$now.$delim;
  5670. $newfilename = $filepath.$file['name'];
  5671. // Move the uploaded file from the temp directory into the incidents attachment dir
  5672. $mv = move_uploaded_file($file['tmp_name'], $newfilename);
  5673. if (!$mv) trigger_error('!Error: Problem moving attachment from temp directory to: '.$newfilename, E_USER_WARNING);
  5674. // Check file size before attaching
  5675. if ($file['size'] > $att_max_filesize)
  5676. {
  5677. trigger_error("User Error: Attachment too large or file upload error - size: {$file['size']}", E_USER_WARNING);
  5678. // throwing an error isn't the nicest thing to do for the user but there seems to be no guaranteed
  5679. // way of checking file sizes at the client end before the attachment is uploaded. - INL
  5680. return FALSE;
  5681. }
  5682. else
  5683. {
  5684. if (!empty($sit[2]))
  5685. {
  5686. $usertype = 'user';
  5687. $userid = $sit[2];
  5688. }
  5689. else
  5690. {
  5691. $usertype = 'contact';
  5692. $userid = $_SESSION['contactid'];
  5693. }
  5694. $sql = "INSERT INFO `{$GLOBALS['dbFiles']}`
  5695. (category, filename, size, userid, usertype, path, filedate, refid)
  5696. VALUES
  5697. ('{$type}', '{$file['name']}', '{$file['size']}', '{$userid}', '{$usertype}', '{$filepath}', '{$now}', '{$id}')";
  5698. $result = mysql_query($sql);
  5699. if (mysql_error()) trigger_error("MySQL Query Error ".mysql_error(), E_USER_ERROR);
  5700. return $returnpath;
  5701. }
  5702. }
  5703. }
  5704. /**
  5705. * Function to return a HTML table row with two columns.
  5706. * Giving radio boxes for groups and if the level is 'management' then you are able to view the users (de)selcting
  5707. * @param string $title - text to go in the first column
  5708. * @param string $level either management or engineer, management is able to (de)select users
  5709. * @param int $groupid Defalt group to select
  5710. * @param string $type - Type of buttons to use either radio or checkbox
  5711. * @return table row of format <tr><th /><td /></tr>
  5712. * @author Paul Heaney
  5713. */
  5714. function group_user_selector($title, $level="engineer", $groupid, $type='radio')
  5715. {
  5716. global $dbUsers, $dbGroups;
  5717. $str .= "<tr><th>{$title}</th>";
  5718. $str .= "<td align='center'>";
  5719. $sql = "SELECT DISTINCT(g.name), g.id FROM `{$dbUsers}` AS u, `{$dbGroups}` AS g ";
  5720. $sql .= "WHERE u.status > 0 AND u.groupid = g.id ORDER BY g.name";
  5721. $result = mysql_query($sql);
  5722. if (mysql_error()) trigger_error("MySQL Query Error ".mysql_error(), E_USER_WARNING);
  5723. while ($row = mysql_fetch_object($result))
  5724. {
  5725. if ($type == 'radio')
  5726. {
  5727. $str .= "<input type='radio' name='group' id='{$row->name}' onclick='groupMemberSelect(\"{$row->name}\", \"TRUE\")' ";
  5728. }
  5729. elseif ($type == 'checkbox')
  5730. {
  5731. $str .= "<input type='checkbox' name='{$row->name}' id='{$row->name}' onclick='groupMemberSelect(\"{$row->name}\", \"FALSE\")' ";
  5732. }
  5733. if ($groupid == $row->id)
  5734. {
  5735. $str .= " checked='checked' ";
  5736. $groupname = $row->name;
  5737. }
  5738. $str .= "/>{$row->name} \n";
  5739. }
  5740. $str .="<br />";
  5741. $sql = "SELECT u.id, u.realname, g.name FROM `{$dbUsers}` AS u, `{$dbGroups}` AS g ";
  5742. $sql .= "WHERE u.status > 0 AND u.groupid = g.id ORDER BY username";
  5743. $result = mysql_query($sql);
  5744. if (mysql_error()) trigger_error("MySQL Query Error ".mysql_error(), E_USER_ERROR);
  5745. if ($level == "management")
  5746. {
  5747. $str .= "<select name='users[]' id='include' multiple='multiple' size='20'>";
  5748. }
  5749. elseif ($level == "engineer")
  5750. {
  5751. $str .= "<select name='users[]' id='include' multiple='multiple' size='20' style='display:none'>";
  5752. }
  5753. while ($row = mysql_fetch_object($result))
  5754. {
  5755. $str .= "<option value='{$row->id}'>{$row->realname} ({$row->name})</option>\n";
  5756. }
  5757. $str .= "</select>";
  5758. $str .= "<br />";
  5759. if ($level == "engineer")
  5760. {
  5761. $visibility = " style='display:none'";
  5762. }
  5763. $str .= "<input type='button' id='selectall' onclick='doSelect(true, \"include\")' value='Select All' {$visibility} />";
  5764. $str .= "<input type='button' id='clearselection' onclick='doSelect(false, \"include\")' value='Clear Selection' {$visibility} />";
  5765. $str .= "</td>";
  5766. $str .= "</tr>\n";
  5767. // FIXME make this XHTML valid
  5768. $str .= "<script type='text/javascript'>\n//<![CDATA[\ngroupMemberSelect(\"{$groupname}\", \"TRUE\");\n//]]>\n</script>";
  5769. return $str;
  5770. }
  5771. /**
  5772. * Output html for the 'time to next action' box
  5773. * Used in add incident and update incident
  5774. * @param string $formid. HTML ID of the form containing the controls
  5775. * @return $html string html to output
  5776. * @author Kieran Hogg
  5777. * @TODO populate $id
  5778. */
  5779. function show_next_action($formid)
  5780. {
  5781. global $now, $strAM, $strPM;
  5782. $html = "{$GLOBALS['strPlaceIncidentInWaitingQueue']}<br />";
  5783. $oldtimeofnextaction = incident_timeofnextaction($id); //FIXME $id never populated
  5784. if ($oldtimeofnextaction < 1)
  5785. {
  5786. $oldtimeofnextaction = $now;
  5787. }
  5788. $wait_time = ($oldtimeofnextaction - $now);
  5789. $na_days = floor($wait_time / 86400);
  5790. $na_remainder = $wait_time % 86400;
  5791. $na_hours = floor($na_remainder / 3600);
  5792. $na_remainder = $wait_time % 3600;
  5793. $na_minutes = floor($na_remainder / 60);
  5794. if ($na_days < 0) $na_days = 0;
  5795. if ($na_hours < 0) $na_hours = 0;
  5796. if ($na_minutes < 0) $na_minutes = 0;
  5797. $html .= "<label>";
  5798. $html .= "<input checked='checked' type='radio' name='timetonextaction' ";
  5799. $html .= "id='ttna_none' onchange=\"update_ttna();\" ";
  5800. // $html .= "onclick=\"$('timetonextaction_days').value = ''; window.document.updateform.";
  5801. // $html .= "timetonextaction_hours.value = ''; window.document.updateform."; timetonextaction_minutes.value = '';\"
  5802. $html .= " value='None' />{$GLOBALS['strNo']}";
  5803. $html .= "</label><br />";
  5804. $html .= "<label><input type='radio' name='timetonextaction' ";
  5805. $html .= "id='ttna_time' value='time' onchange=\"update_ttna();\" />";
  5806. $html .= "{$GLOBALS['strForXDaysHoursMinutes']}</label><br />\n";
  5807. $html .= "<span id='ttnacountdown'";
  5808. if (empty($na_days) AND
  5809. empty($na_hours) AND
  5810. empty($na_minutes))
  5811. {
  5812. $html .= " style='display: none;'";
  5813. }
  5814. $html .= ">";
  5815. $html .= "&nbsp;&nbsp;&nbsp;<input name='timetonextaction_days' ";
  5816. $html .= " id='timetonextaction_days' value='{$na_days}' maxlength='3' ";
  5817. $html .= "onclick=\"$('ttna_time').checked = true;\" ";
  5818. $html .= "size='3' /> {$GLOBALS['strDays']}&nbsp;";
  5819. $html .= "<input maxlength='2' name='timetonextaction_hours' ";
  5820. $html .= "id='timetonextaction_hours' value='{$na_hours}' ";
  5821. $html .= "onclick=\"$('ttna_time').checked = true;\" ";
  5822. $html .= "size='3' /> {$GLOBALS['strHours']}&nbsp;";
  5823. $html .= "<input maxlength='2' name='timetonextaction_minutes' id='";
  5824. $html .= "timetonextaction_minutes' value='{$na_minutes}' ";
  5825. $html .= "onclick=\"$('ttna_time').checked = true;\" ";
  5826. $html .= "size='3' /> {$GLOBALS['strMinutes']}";
  5827. $html .= "<br />\n</span>";
  5828. $html .= "<label><input type='radio' name='timetonextaction' id='ttna_date' ";
  5829. $html .= "value='date' onchange=\"update_ttna();\" />";
  5830. $html .= "{$GLOBALS['strUntilSpecificDateAndTime']}</label><br />\n";
  5831. $html .= "<div id='ttnadate' style='display: none;'>";
  5832. $html .= "<input name='date' id='timetonextaction_date' size='10' value='{$date}' ";
  5833. $html .= "onclick=\"$('ttna_date').checked = true;\" /> ";
  5834. $html .= date_picker("{$formid}.timetonextaction_date");
  5835. $html .= " <select name='timeoffset' id='timeoffset' ";
  5836. $html .= "onclick=\"$('ttna_date').checked = true;\" >";
  5837. $html .= "<option value='0'></option>";
  5838. $html .= "<option value='0'>8:00 $strAM</option>";
  5839. $html .= "<option value='1'>9:00 $strAM</option>";
  5840. $html .= "<option value='2'>10:00 $strAM</option>";
  5841. $html .= "<option value='3'>11:00 $strAM</option>";
  5842. $html .= "<option value='4'>12:00 $strPM</option>";
  5843. $html .= "<option value='5'>1:00 $strPM</option>";
  5844. $html .= "<option value='6'>2:00 $strPM</option>";
  5845. $html .= "<option value='7'>3:00 $strPM</option>";
  5846. $html .= "<option value='8'>4:00 $strPM</option>";
  5847. $html .= "<option value='9'>5:00 $strPM</option>";
  5848. $html .= "</select>";
  5849. $html .= "<br />\n</div>";
  5850. return $html;
  5851. }
  5852. /**
  5853. * Output the html for a KB article
  5854. *
  5855. * @param int $id ID of the KB article
  5856. * @param string $mode whether this is internal or external facing, defaults to internal
  5857. * @return string $html kb article html
  5858. * @author Kieran Hogg
  5859. */
  5860. function kb_article($id, $mode='internal')
  5861. {
  5862. global $CONFIG, $iconset;
  5863. $id = intval($id);
  5864. if (!is_number($id) OR $id == 0)
  5865. {
  5866. trigger_error("Incorrect KB ID", E_USER_ERROR);
  5867. include (APPLICATION_INCPATH . 'htmlfooter.inc.php');
  5868. exit;
  5869. }
  5870. $sql = "SELECT * FROM `{$GLOBALS['dbKBArticles']}` WHERE docid='{$id}' LIMIT 1";
  5871. $result = mysql_query($sql);
  5872. if (mysql_error()) trigger_error("MySQL Query Error ".mysql_error(), E_USER_WARNING);
  5873. $kbarticle = mysql_fetch_object($result);
  5874. if (empty($kbarticle->title))
  5875. {
  5876. $kbarticle->title = $GLOBALS['strUntitled'];
  5877. }
  5878. $html .= "<div id='kbarticle'";
  5879. if ($kbarticle->distribution == 'private') $html .= " class='expired'";
  5880. if ($kbarticle->distribution == 'restricted') $html .= " class='urgent'";
  5881. $html .= ">";
  5882. $html .= "<h2 class='kbtitle'>{$kbarticle->title}</h2>";
  5883. if (!empty($kbarticle->distribution) AND $kbarticle->distribution != 'public')
  5884. {
  5885. $html .= "<h2 class='kbdistribution'>{$GLOBALS['strDistribution']}: ".ucfirst($kbarticle->distribution)."</h2>";
  5886. }
  5887. // Lookup what software this applies to
  5888. $ssql = "SELECT * FROM `{$GLOBALS['dbKBSoftware']}` AS kbs, `{$GLOBALS['dbSoftware']}` AS s ";
  5889. $ssql .= "WHERE kbs.softwareid = s.id AND kbs.docid = '{$id}' ";
  5890. $ssql .= "ORDER BY s.name";
  5891. $sresult = mysql_query($ssql);
  5892. if (mysql_error()) trigger_error("MySQL Query Error ".mysql_error(), E_USER_WARNING);
  5893. if (mysql_num_rows($sresult) >= 1)
  5894. {
  5895. $html .= "<h3>{$GLOBALS['strEnvironment']}</h3>";
  5896. $html .= "<p>{$GLOBALS['strTheInfoInThisArticle']}:</p>\n";
  5897. $html .= "<ul>\n";
  5898. while ($kbsoftware = mysql_fetch_object($sresult))
  5899. {
  5900. $html .= "<li>{$kbsoftware->name}</li>\n";
  5901. }
  5902. $html .= "</ul>\n";
  5903. }
  5904. $csql = "SELECT * FROM `{$GLOBALS['dbKBContent']}` WHERE docid='{$id}' ";
  5905. $cresult = mysql_query($csql);
  5906. if (mysql_error()) trigger_error("MySQL Query Error ".mysql_error(), E_USER_WARNING);
  5907. $restrictedcontent = 0;
  5908. while ($kbcontent = mysql_fetch_object($cresult))
  5909. {
  5910. switch ($kbcontent->distribution)
  5911. {
  5912. case 'private':
  5913. if ($mode != 'internal')
  5914. {
  5915. echo "<p class='error'>{$GLOBALS['strPermissionDenied']}</p>";
  5916. include (APPLICATION_INCPATH . 'htmlfooter.inc.php');
  5917. exit;
  5918. }
  5919. $html .= "<div class='kbprivate'><h3>{$kbcontent->header} (private)</h3>";
  5920. $restrictedcontent++;
  5921. break;
  5922. case 'restricted':
  5923. if ($mode != 'internal')
  5924. {
  5925. echo "<p class='error'>{$GLOBALS['strPermissionDenied']}</p>";
  5926. include (APPLICATION_INCPATH . 'htmlfooter.inc.php');
  5927. exit;
  5928. }
  5929. $html .= "<div class='kbrestricted'><h3>{$kbcontent->header}</h3>";
  5930. $restrictedcontent++;
  5931. break;
  5932. default:
  5933. $html .= "<div><h3>{$kbcontent->header}</h3>";
  5934. }
  5935. //$html .= "<{$kbcontent->headerstyle}>{$kbcontent->header}</{$kbcontent->headerstyle}>\n";
  5936. $html .= '';
  5937. $kbcontent->content=nl2br($kbcontent->content);
  5938. $search = array("/(?<!quot;|[=\"]|:\/{2})\b((\w+:\/{2}|www\.).+?)"."(?=\W*([<>\s]|$))/i", "/(([\w\.]+))(@)([\w\.]+)\b/i");
  5939. $replace = array("<a href=\"$1\">$1</a>", "<a href=\"mailto:$0\">$0</a>");
  5940. $kbcontent->content = preg_replace("/href=\"www/i", "href=\"http://www", preg_replace ($search, $replace, $kbcontent->content));
  5941. $html .= bbcode($kbcontent->content);
  5942. $author[]=$kbcontent->ownerid;
  5943. $html .= "</div>\n";
  5944. }
  5945. if ($restrictedcontent > 0)
  5946. {
  5947. $html .= "<h3>{$GLOBALS['strKey']}</h3>";
  5948. $html .= "<p><span class='keykbprivate'>{$GLOBALS['strPrivate']}</span>".help_link('KBPrivate')." &nbsp; ";
  5949. $html .= "<span class='keykbrestricted'>{$GLOBALS['strRestricted']}</span>".help_link('KBRestricted')."</p>";
  5950. }
  5951. $html .= "<h3>{$GLOBALS['strArticle']}</h3>";
  5952. //$html .= "<strong>{$GLOBALS['strDocumentID']}</strong>: ";
  5953. $html .= "<p><strong>{$CONFIG['kb_id_prefix']}".leading_zero(4,$kbarticle->docid)."</strong> ";
  5954. $pubdate = mysql2date($kbarticle->published);
  5955. if ($pubdate > 0)
  5956. {
  5957. $html .= "{$GLOBALS['strPublished']} ";
  5958. $html .= ldate($CONFIG['dateformat_date'],$pubdate)."<br />";
  5959. }
  5960. if ($mode == 'internal')
  5961. {
  5962. if (is_array($author))
  5963. {
  5964. $author=array_unique($author);
  5965. $countauthors=count($author);
  5966. $count=1;
  5967. if ($countauthors > 1)
  5968. {
  5969. $html .= "<strong>{$GLOBALS['strAuthors']}</strong>:<br />";
  5970. }
  5971. else
  5972. {
  5973. $html .= "<strong>{$GLOBALS['strAuthor']}:</strong> ";
  5974. }
  5975. foreach ($author AS $authorid)
  5976. {
  5977. $html .= user_realname($authorid,TRUE);
  5978. if ($count < $countauthors) $html .= ", " ;
  5979. $count++;
  5980. }
  5981. }
  5982. }
  5983. $html .= "<br />";
  5984. if (!empty($kbarticle->keywords))
  5985. {
  5986. $html .= "<strong>{$GLOBALS['strKeywords']}</strong>: ";
  5987. if ($mode == 'internal')
  5988. {
  5989. $html .= preg_replace("/\[([0-9]+)\]/", "<a href=\"incident_details.php?id=$1\" target=\"_blank\">$0</a>", $kbarticle->keywords);
  5990. }
  5991. else
  5992. {
  5993. $html .= $kbarticle->keywords;
  5994. }
  5995. $html .= "<br />";
  5996. }
  5997. //$html .= "<h3>{$GLOBALS['strDisclaimer']}</h3>";
  5998. $html .= "</p><hr />";
  5999. $html .= $CONFIG['kb_disclaimer_html'];
  6000. $html .= "</div>";
  6001. if ($mode == 'internal')
  6002. {
  6003. $html .= "<p align='center'>";
  6004. $html .= "<a href='kb.php'>{$GLOBALS['strBackToList']}</a> | ";
  6005. $html .= "<a href='kb_article.php?id={$kbarticle->docid}'>{$GLOBALS['strEdit']}</a></p>";
  6006. }
  6007. return $html;
  6008. }
  6009. /**
  6010. * Output the html for the edit site form
  6011. *
  6012. * @param int $site ID of the site
  6013. * @param string $mode whether this is internal or external facing, defaults to internal
  6014. * @return string $html edit site form html
  6015. * @author Kieran Hogg
  6016. */
  6017. function show_edit_site($site, $mode='internal')
  6018. {
  6019. global $CONFIG;
  6020. $sql = "SELECT * FROM `{$GLOBALS['dbSites']}` WHERE id='$site' ";
  6021. $siteresult = mysql_query($sql);
  6022. if (mysql_error()) trigger_error("MySQL Query Error ".mysql_error(), E_USER_WARNING);
  6023. while ($siterow = mysql_fetch_array($siteresult))
  6024. {
  6025. if ($mode == 'internal')
  6026. {
  6027. $html .= "<h2>".icon('site', 32)." {$GLOBALS['strEditSite']}: {$site} - ";
  6028. $html .= site_name($site)."</h2>";
  6029. }
  6030. else
  6031. {
  6032. $html .= "<h2>".icon('site', 32)." ".site_name($site)."</h2>";
  6033. }
  6034. $html .= "<form name='edit_site' action='{$_SERVER['PHP_SELF']}";
  6035. $html .= "?action=update' method='post' onsubmit='return ";
  6036. $html .= "confirm_action(\"{$GLOBALS['strAreYouSureMakeTheseChanges']}\")'>";
  6037. $html .= "<table align='center' class='vertical'>";
  6038. $html .= "<tr><th>{$GLOBALS['strName']}:</th>";
  6039. $html .= "<td><input class='required' maxlength='50' name='name' size='40' value='{$siterow['name']}' />";
  6040. $html .= "<span class='required'>{$GLOBALS['strRequired']}</span></td></tr>\n";
  6041. if ($mode == 'internal')
  6042. {
  6043. $html .= "<tr><th>{$GLOBALS['strTags']}:</th><td><textarea rows='2' cols='60' name='tags'>";
  6044. $html .= list_tags($site, TAG_SITE, false)."</textarea>\n";
  6045. }
  6046. $html .= "<tr><th>{$GLOBALS['strDepartment']}:</th>";
  6047. $html .= "<td><input maxlength='50' name='department' size='40' value='{$siterow['department']}' />";
  6048. $html .= "</td></tr>\n";
  6049. $html .= "<tr><th>{$GLOBALS['strAddress1']}:</th>";
  6050. $html .= "<td><input maxlength='50' name='address1'";
  6051. $html .= "size='40' value='{$siterow['address1']}' />";
  6052. $html .= "</td></tr>\n";
  6053. $html .= "<tr><th>{$GLOBALS['strAddress2']}: </th><td><input maxlength='50' name='address2' size='40' value='{$siterow['address2']}' /></td></tr>\n";
  6054. $html .= "<tr><th>{$GLOBALS['strCity']}:</th><td><input maxlength='255' name='city' size='40' value='{$siterow['city']}' /></td></tr>\n";
  6055. $html .= "<tr><th>{$GLOBALS['strCounty']}:</th><td><input maxlength='255' name='county' size='40' value='{$siterow['county']}' /></td></tr>\n";
  6056. $html .= "<tr><th>{$GLOBALS['strPostcode']}:</th><td><input maxlength='255' name='postcode' size='40' value='{$siterow['postcode']}' /></td></tr>\n";
  6057. $html .= "<tr><th>{$GLOBALS['strCountry']}:</th><td>".country_drop_down('country', $siterow['country'])."</td></tr>\n";
  6058. $html .= "<tr><th>{$GLOBALS['strTelephone']}:</th><td>";
  6059. $html .= "<input class='required' maxlength='255' name='telephone' size='40' value='{$siterow['telephone']}' />";
  6060. $html .= "<span class='required'>{$GLOBALS['strRequired']}</span></td></tr>\n";
  6061. $html .= "<tr><th>{$GLOBALS['strFax']}:</th><td>";
  6062. $html .= "<input maxlength='255' name='fax' size='40' value='{$siterow['fax']}' /></td></tr>\n";
  6063. $html .= "<tr><th>{$GLOBALS['strEmail']}:</th><td>";
  6064. $html .= "<input class='required' maxlength='255' name='email' size='40' value='{$siterow['email']}' />";
  6065. $html .= "<span class='required'>{$GLOBALS['strRequired']}</span></td></tr>\n";
  6066. $html .= "<tr><th>{$GLOBALS['strWebsite']}:</th><td>";
  6067. $html .= "<input maxlength='255' name='websiteurl' size='40' value='{$siterow['websiteurl']}' /></td></tr>\n";
  6068. $html .= "<tr><th>{$GLOBALS['strSiteType']}:</th><td>\n";
  6069. $html .= sitetype_drop_down('typeid', $siterow['typeid']);
  6070. $html .= "</td></tr>\n";
  6071. if ($mode == 'internal')
  6072. {
  6073. $html .= "<tr><th>{$GLOBALS['strSalesperson']}:</th><td>";
  6074. $html .= user_drop_down('owner', $siterow['owner'], $accepting = FALSE, '', '', TRUE);
  6075. $html .= "</td></tr>\n";
  6076. }
  6077. if ($mode == 'internal')
  6078. {
  6079. $html .= "<tr><th>{$GLOBALS['strIncidentPool']}:</th>";
  6080. $incident_pools = explode(',', "{$GLOBALS['strNone']},{$CONFIG['incident_pools']}");
  6081. if (array_key_exists($siterow['freesupport'], $incident_pools) == FALSE)
  6082. {
  6083. array_unshift($incident_pools,$siterow['freesupport']);
  6084. }
  6085. $html .= "<td>".array_drop_down($incident_pools,'incident_poolid',$siterow['freesupport'])."</td></tr>";
  6086. $html .= "<tr><th>{$GLOBALS['strActive']}:</th><td><input type='checkbox' name='active' ";
  6087. if ($siterow['active'] == 'true')
  6088. {
  6089. $html .= "checked='".$siterow['active']."'";
  6090. }
  6091. $html .= " value='true' /></td></tr>\n";
  6092. $html .= "<tr><th>{$GLOBALS['strNotes']}:</th><td>";
  6093. $html .= "<textarea rows='5' cols='30' name='notes'>{$siterow['notes']}</textarea>";
  6094. $html .= "</td></tr>\n";
  6095. }
  6096. plugin_do('edit_site_form');
  6097. $html .= "</table>\n";
  6098. $html .= "<input name='site' type='hidden' value='$site' />";
  6099. $html .= "<p><input name='submit' type='submit' value='{$GLOBALS['strSave']}' /></p>";
  6100. $html .= "</form>";
  6101. }
  6102. return $html;
  6103. }
  6104. /**
  6105. * Output the html for an add contact form
  6106. *
  6107. * @param int $siteid - the site you want to add the contact to
  6108. * @param string $mode - whether this is internal or external facing, defaults to internal
  6109. * @return string $html add contact form html
  6110. * @author Kieran Hogg
  6111. */
  6112. function show_add_contact($siteid = 0, $mode = 'internal')
  6113. {
  6114. global $CONFIG;
  6115. $returnpage = cleanvar($_REQUEST['return']);
  6116. if (!empty($_REQUEST['name']))
  6117. {
  6118. $name = explode(' ',cleanvar(urldecode($_REQUEST['name'])), 2);
  6119. $_SESSION['formdata']['add_contact']['forenames'] = ucfirst($name[0]);
  6120. $_SESSION['formdata']['add_contact']['surname'] = ucfirst($name[1]);
  6121. }
  6122. $html = show_form_errors('add_contact');
  6123. clear_form_errors('add_contact');
  6124. $html .= "<h2>".icon('contact', 32)." ";
  6125. $html .= "{$GLOBALS['strNewContact']}</h2>";
  6126. if ($mode == 'internal')
  6127. {
  6128. $html .= "<h5 class='warning'>{$GLOBALS['strAvoidDupes']}</h5>";
  6129. }
  6130. $html .= "<form name='contactform' action='{$_SERVER['PHP_SELF']}' ";
  6131. $html .= "method='post' onsubmit=\"return confirm_action('{$GLOBALS['strAreYouSureAdd']}')\">";
  6132. $html .= "<table align='center' class='vertical'>";
  6133. $html .= "<tr><th>{$GLOBALS['strName']}</th>\n";
  6134. $html .= "<td>";
  6135. $html .= "\n<table><tr><td align='center'>{$GLOBALS['strTitle']}<br />";
  6136. $html .= "<input maxlength='50' name='courtesytitle' title=\"";
  6137. $html .= "{$GLOBALS['strCourtesyTitle']}\" size='7'";
  6138. if ($_SESSION['formdata']['add_contact']['courtesytitle'] != '')
  6139. {
  6140. $html .= "value='{$_SESSION['formdata']['add_contact']['courtesytitle']}'";
  6141. }
  6142. $html .= "/></td>\n";
  6143. $html .= "<td align='center'>{$GLOBALS['strForenames']}<br />";
  6144. $html .= "<input class='required' maxlength='100' name='forenames' ";
  6145. $html .= "size='15' title=\"{$GLOBALS['strForenames']}\"";
  6146. if ($_SESSION['formdata']['add_contact']['forenames'] != '')
  6147. {
  6148. $html .= "value='{$_SESSION['formdata']['add_contact']['forenames']}'";
  6149. }
  6150. $html .= "/></td>\n";
  6151. $html .= "<td align='center'>{$GLOBALS['strSurname']}<br />";
  6152. $html .= "<input class='required' maxlength='100' name='surname' ";
  6153. $html .= "size='20' title=\"{$GLOBALS['strSurname']}\"";
  6154. if ($_SESSION['formdata']['add_contact']['surname'] != '')
  6155. {
  6156. $html .= "value='{$_SESSION['formdata']['add_contact']['surname']}'";
  6157. }
  6158. $html .= " /> <span class='required'>{$GLOBALS['strRequired']}</span></td></tr>\n";
  6159. $html .= "</table>\n</td></tr>\n";
  6160. $html .= "<tr><th>{$GLOBALS['strJobTitle']}</th><td><input maxlength='255'";
  6161. $html .= " name='jobtitle' size='35' title=\"{$GLOBALS['strJobTitle']}\"";
  6162. if ($_SESSION['formdata']['add_contact']['jobtitle'] != '')
  6163. {
  6164. $html .= "value='{$_SESSION['formdata']['add_contact']['jobtitle']}'";
  6165. }
  6166. $html .= " /></td></tr>\n";
  6167. if ($mode == 'internal')
  6168. {
  6169. $html .= "<tr><th>{$GLOBALS['strSite']}</th><td>";
  6170. $html .= site_drop_down('siteid',$siteid, TRUE)."<span class='required'>{$GLOBALS['strRequired']}</span></td></tr>\n";
  6171. }
  6172. else
  6173. {
  6174. // For external always force the site to be the session site
  6175. $html .= "<input type='hidden' name='siteid' value='{$_SESSION['siteid']}' />";
  6176. }
  6177. $html .= "<tr><th>{$GLOBALS['strDepartment']}</th><td><input maxlength='255' name='department' size='35'";
  6178. if ($_SESSION['formdata']['add_contact']['department'] != '')
  6179. {
  6180. $html .= "value='{$_SESSION['formdata']['add_contact']['department']}'";
  6181. }
  6182. $html .= "/></td></tr>\n";
  6183. $html .= "<tr><th>{$GLOBALS['strEmail']}</th><td>";
  6184. $html .= "<input class='required' maxlength='100' name='email' size='35'";
  6185. if ($_SESSION['formdata']['add_contact']['email'])
  6186. {
  6187. $html .= "value='{$_SESSION['formdata']['add_contact']['email']}'";
  6188. }
  6189. $html .= "/><span class='required'>{$GLOBALS['strRequired']}</span> ";
  6190. $html .= "<label>";
  6191. $html .= html_checkbox('dataprotection_email', 'No');
  6192. $html .= "{$GLOBALS['strEmail']} {$GLOBALS['strDataProtection']}</label>".help_link("EmailDataProtection");
  6193. $html .= "</td></tr>\n";
  6194. $html .= "<tr><th>{$GLOBALS['strTelephone']}</th><td><input maxlength='50' name='phone' size='35'";
  6195. if ($_SESSION['formdata']['add_contact']['phone'] != '')
  6196. {
  6197. $html .= "value='{$_SESSION['formdata']['add_contact']['phone']}'";
  6198. }
  6199. $html .= "/> ";
  6200. $html .= "<label>";
  6201. $html .= html_checkbox('dataprotection_phone', 'No');
  6202. $html .= "{$GLOBALS['strTelephone']} {$GLOBALS['strDataProtection']}</label>".help_link("TelephoneDataProtection");
  6203. $html .= "</td></tr>\n";
  6204. $html .= "<tr><th>{$GLOBALS['strMobile']}</th><td><input maxlength='100' name='mobile' size='35'";
  6205. if ($_SESSION['formdata']['add_contact']['mobile'] != '')
  6206. {
  6207. $html .= "value='{$_SESSION['formdata']['add_contact']['mobile']}'";
  6208. }
  6209. $html .= "/></td></tr>\n";
  6210. $html .= "<tr><th>{$GLOBALS['strFax']}</th><td><input maxlength='50' name='fax' size='35'";
  6211. if ($_SESSION['formdata']['add_contact']['fax'])
  6212. {
  6213. $html .= "value='{$_SESSION['formdata']['add_contact']['fax']}'";
  6214. }
  6215. $html .= "/></td></tr>\n";
  6216. $html .= "<tr><th>{$GLOBALS['strAddress']}</th><td><label>";
  6217. $html .= html_checkbox('dataprotection_address', 'No');
  6218. $html .= " {$GLOBALS['strAddress']} {$GLOBALS['strDataProtection']}</label>";
  6219. $html .= help_link("AddressDataProtection")."</td></tr>\n";
  6220. $html .= "<tr><th></th><td><label><input type='checkbox' name='usesiteaddress' value='yes' onclick=\"$('hidden').toggle();\" /> {$GLOBALS['strSpecifyAddress']}</label></td></tr>\n";
  6221. $html .= "<tbody id='hidden' style='display:none'>";
  6222. $html .= "<tr><th>{$GLOBALS['strAddress1']}</th>";
  6223. $html .= "<td><input maxlength='255' name='address1' size='35' /></td></tr>\n";
  6224. $html .= "<tr><th>{$GLOBALS['strAddress2']}</th>";
  6225. $html .= "<td><input maxlength='255' name='address2' size='35' /></td></tr>\n";
  6226. $html .= "<tr><th>{$GLOBALS['strCity']}</th><td><input maxlength='255' name='city' size='35' /></td></tr>\n";
  6227. $html .= "<tr><th>{$GLOBALS['strCounty']}</th><td><input maxlength='255' name='county' size='35' /></td></tr>\n";
  6228. $html .= "<tr><th>{$GLOBALS['strCountry']}</th><td>";
  6229. $html .= country_drop_down('country', $CONFIG['home_country'])."</td></tr>\n";
  6230. $html .= "<tr><th>{$GLOBALS['strPostcode']}</th><td><input maxlength='255' name='postcode' size='35' /></td></tr>\n";
  6231. $html .= "</tbody>";
  6232. if ($mode == 'internal')
  6233. {
  6234. $html .= "<tr><th>{$GLOBALS['strNotes']}</th><td><textarea cols='60' rows='5' name='notes'>";
  6235. if ($_SESSION['formdata']['add_contact']['notes'] != '')
  6236. {
  6237. $html .= $_SESSION['formdata']['add_contact']['notes'];
  6238. }
  6239. $html .= "</textarea></td></tr>\n";
  6240. }
  6241. $html .= "<tr><th>{$GLOBALS['strEmailDetails']}</th>";
  6242. // Check the box to send portal details, only if portal is enabled
  6243. $html .= "<td><input type='checkbox' name='emaildetails'";
  6244. if ($CONFIG['portal'] == TRUE) $html .= " checked='checked'";
  6245. else $html .= " disabled='disabled'";
  6246. $html .= ">";
  6247. $html .= "<label for='emaildetails'>{$GLOBALS['strEmailContactLoginDetails']}</td></tr>";
  6248. $html .= "</table>\n\n";
  6249. if (!empty($returnpage)) $html .= "<input type='hidden' name='return' value='{$returnpage}' />";
  6250. $html .= "<p><input name='submit' type='submit' value=\"{$GLOBALS['strAddContact']}\" /></p>";
  6251. $html .= "</form>\n";
  6252. //cleanup form vars
  6253. clear_form_data('add_contact');
  6254. return $html;
  6255. }
  6256. /**
  6257. * Procceses a new contact
  6258. *
  6259. * @author Kieran Hogg
  6260. */
  6261. function process_add_contact($mode = 'internal')
  6262. {
  6263. global $now, $CONFIG, $dbContacts, $sit;
  6264. // Add new contact
  6265. // External variables
  6266. $siteid = mysql_real_escape_string($_REQUEST['siteid']);
  6267. $email = strtolower(cleanvar($_REQUEST['email']));
  6268. $dataprotection_email = mysql_real_escape_string($_REQUEST['dataprotection_email']);
  6269. $dataprotection_phone = mysql_real_escape_string($_REQUEST['dataprotection_phone']);
  6270. $dataprotection_address = mysql_real_escape_string($_REQUEST['dataprotection_address']);
  6271. $username = cleanvar($_REQUEST['username']);
  6272. $courtesytitle = cleanvar($_REQUEST['courtesytitle']);
  6273. $forenames = cleanvar($_REQUEST['forenames']);
  6274. $surname = cleanvar($_REQUEST['surname']);
  6275. $jobtitle = cleanvar($_REQUEST['jobtitle']);
  6276. $address1 = cleanvar($_REQUEST['address1']);
  6277. $address2 = cleanvar($_REQUEST['address2']);
  6278. $city = cleanvar($_REQUEST['city']);
  6279. $county = cleanvar($_REQUEST['county']);
  6280. if (!empty($address1)) $country = cleanvar($_REQUEST['country']);
  6281. else $country='';
  6282. $postcode = cleanvar($_REQUEST['postcode']);
  6283. $phone = cleanvar($_REQUEST['phone']);
  6284. $mobile = cleanvar($_REQUEST['mobile']);
  6285. $fax = cleanvar($_REQUEST['fax']);
  6286. $department = cleanvar($_REQUEST['department']);
  6287. $notes = cleanvar($_REQUEST['notes']);
  6288. $returnpage = cleanvar($_REQUEST['return']);
  6289. $_SESSION['formdata']['add_contact'] = $_REQUEST;
  6290. $errors = 0;
  6291. // check for blank name
  6292. if ($surname == '')
  6293. {
  6294. $errors++;
  6295. $_SESSION['formerrors']['add_contact']['surname'] = $GLOBALS['strMustEnterSurname'];
  6296. }
  6297. // check for blank site
  6298. if ($siteid == '')
  6299. {
  6300. $errors++;
  6301. $_SESSION['formerrors']['add_contact']['siteid'] = $GLOBALS['strMustSelectCustomerSite'];
  6302. }
  6303. // check for blank email
  6304. if ($email == '' OR $email=='none' OR $email=='n/a')
  6305. {
  6306. $errors++;
  6307. $_SESSION['formerrors']['add_contact']['email'] = $GLOBALS['strMustEnterEmail'];
  6308. }
  6309. if ($siteid==0 OR $siteid=='')
  6310. {
  6311. $errors++;
  6312. $_SESSION['formerrors']['add_contact']['siteid'] = $GLOBALS['strMustSelectSite'];
  6313. }
  6314. // Check this is not a duplicate
  6315. $sql = "SELECT id FROM `{$dbContacts}` WHERE email='$email' AND LCASE(surname)=LCASE('$surname') LIMIT 1";
  6316. $result = mysql_query($sql);
  6317. if (mysql_num_rows($result) >= 1)
  6318. {
  6319. $errors++;
  6320. $_SESSION['formerrors']['add_contact']['duplicate'] = $GLOBALS['strContactRecordExists'];
  6321. }
  6322. // add contact if no errors
  6323. if ($errors == 0)
  6324. {
  6325. if (!empty($dataprotection_email))
  6326. {
  6327. $dataprotection_email = 'Yes';
  6328. }
  6329. else
  6330. {
  6331. $dataprotection_email = 'No';
  6332. }
  6333. if (!empty($dataprotection_phone))
  6334. {
  6335. $dataprotection_phone = 'Yes';
  6336. }
  6337. else
  6338. {
  6339. $dataprotection_phone = 'No';
  6340. }
  6341. if (!empty($dataprotection_address))
  6342. {
  6343. $dataprotection_address = 'Yes';
  6344. }
  6345. else
  6346. {
  6347. $dataprotection_address = 'No';
  6348. }
  6349. // generate username and password
  6350. $username = strtolower(substr($surname, 0, strcspn($surname, " ")));
  6351. $prepassword = generate_password();
  6352. $password = md5($prepassword);
  6353. $sql = "INSERT INTO `{$dbContacts}` (username, password, courtesytitle, forenames, surname, jobtitle, ";
  6354. $sql .= "siteid, address1, address2, city, county, country, postcode, email, phone, mobile, fax, ";
  6355. $sql .= "department, notes, dataprotection_email, dataprotection_phone, dataprotection_address, ";
  6356. $sql .= "timestamp_added, timestamp_modified) ";
  6357. $sql .= "VALUES ('$username', '$password', '$courtesytitle', '$forenames', '$surname', '$jobtitle', ";
  6358. $sql .= "'$siteid', '$address1', '$address2', '$city', '$county', '$country', '$postcode', '$email', ";
  6359. $sql .= "'$phone', '$mobile', '$fax', '$department', '$notes', '$dataprotection_email', ";
  6360. $sql .= "'$dataprotection_phone', '$dataprotection_address', '$now', '$now')";
  6361. $result = mysql_query($sql);
  6362. if (mysql_error()) trigger_error("MySQL Query Error ".mysql_error(), E_USER_ERROR);
  6363. // concatenate username with insert id to make unique
  6364. $newid = mysql_insert_id();
  6365. $username = $username . $newid;
  6366. $sql = "UPDATE `{$dbContacts}` SET username='{$username}' WHERE id='{$newid}'";
  6367. $result = mysql_query($sql);
  6368. if (mysql_error()) trigger_error("MySQL Query Error ".mysql_error(), E_USER_ERROR);
  6369. if (!$result)
  6370. {
  6371. if ($mode == 'internal')
  6372. {
  6373. html_redirect("contact_add.php", FALSE);
  6374. }
  6375. else
  6376. {
  6377. html_redirect("addcontact.php", FALSE);
  6378. }
  6379. }
  6380. else
  6381. {
  6382. clear_form_data('add_contact');
  6383. clear_form_errors('add_contact');
  6384. $sql = "SELECT username, password FROM `{$dbContacts}` WHERE id=$newid";
  6385. $result = mysql_query($sql);
  6386. if (mysql_error()) trigger_error("MySQL Query Error ".mysql_error(), E_USER_WARNING);
  6387. else
  6388. {
  6389. if ($CONFIG['portal'] AND $_POST['emaildetails'] == 'on')
  6390. {
  6391. trigger('TRIGGER_NEW_CONTACT', array('contactid' => $newid, 'prepassword' => $prepassword, 'userid' => $sit[2]));
  6392. }
  6393. if ($returnpage == 'addincident')
  6394. {
  6395. html_redirect("incident_add.php?action=findcontact&contactid={$newid}");
  6396. exit;
  6397. }
  6398. elseif ($mode == 'internal')
  6399. {
  6400. html_redirect("contact_details.php?id={$newid}");
  6401. exit;
  6402. }
  6403. else
  6404. {
  6405. html_redirect("contactdetails.php?id={$newid}");
  6406. exit;
  6407. }
  6408. }
  6409. }
  6410. }
  6411. else
  6412. {
  6413. if ($mode == 'internal')
  6414. {
  6415. html_redirect('contact_add.php', FALSE);
  6416. }
  6417. else
  6418. {
  6419. html_redirect('addcontact.php', FALSE);
  6420. }
  6421. }
  6422. }
  6423. /**
  6424. * Outputs the name of a KB article, used for triggers
  6425. *
  6426. * @param int $kbid ID of the KB article
  6427. * @return string $name kb article name
  6428. * @author Kieran Hogg
  6429. */
  6430. function kb_name($kbid)
  6431. {
  6432. $kbid = intval($kbid);
  6433. $sql = "SELECT title FROM `{$GLOBALS['dbKBArticles']}` WHERE docid='{$kbid}'";
  6434. $result = mysql_query($sql);
  6435. if (mysql_error()) trigger_error("MySQL Query Error ".mysql_error(), E_USER_WARNING);
  6436. else
  6437. {
  6438. $row = mysql_fetch_object($result);
  6439. return $row->title;
  6440. }
  6441. }
  6442. /**
  6443. * Outputs the full base url of the install, e.g. http://www.example.com/
  6444. *
  6445. * @return string base url of the install
  6446. * @author Kieran Hogg
  6447. */
  6448. function application_url()
  6449. {
  6450. global $CONFIG;
  6451. if (empty($CONFIG['application_uriprefix']))
  6452. {
  6453. $url = parse_url($_SERVER['HTTP_REFERER']);
  6454. if ($_SERVER['HTTPS'] == 'off' OR empty($_SERVER['HTTPS']))
  6455. {
  6456. $baseurl = "http://";
  6457. }
  6458. else
  6459. {
  6460. $baseurl = "https://";
  6461. }
  6462. $baseurl .= "{$_SERVER['HTTP_HOST']}";
  6463. }
  6464. else
  6465. {
  6466. $baseurl = "{$CONFIG['application_uriprefix']}";
  6467. }
  6468. $baseurl .= "{$CONFIG['application_webpath']}";
  6469. return $baseurl;
  6470. }
  6471. /**
  6472. * Outputs the product name of a contract
  6473. *
  6474. * @param int $maintid ID of the contract
  6475. * @return string the name of the product
  6476. * @author Kieran Hogg
  6477. */
  6478. function contract_product($maintid)
  6479. {
  6480. $maintid = intval($maintid);
  6481. $productid = db_read_column('product', $GLOBALS['dbMaintenance'], $maintid);
  6482. $sql = "SELECT name FROM `{$GLOBALS['dbProducts']}` WHERE id='{$productid}'";
  6483. $result = mysql_query($sql);
  6484. $productobj = mysql_fetch_object($result);
  6485. if (!empty($productobj->name))
  6486. {
  6487. return $productobj->name;
  6488. }
  6489. else
  6490. {
  6491. return $GLOBALS['strUnknown'];
  6492. }
  6493. }
  6494. /**
  6495. * Outputs the contract's site name
  6496. *
  6497. * @param int $maintid ID of the contract
  6498. * @return string name of the site
  6499. * @author Kieran Hogg
  6500. */
  6501. function contract_site($maintid)
  6502. {
  6503. $maintid = intval($maintid);
  6504. $sql = "SELECT site FROM `{$GLOBALS['dbMaintenance']}` WHERE id='{$maintid}'";
  6505. $result = mysql_query($sql);
  6506. $maintobj = mysql_fetch_object($result);
  6507. $sitename = site_name($maintobj->site);
  6508. if (!empty($sitename))
  6509. {
  6510. return $sitename;
  6511. }
  6512. else
  6513. {
  6514. return $GLOBALS['strUnknown'];
  6515. }
  6516. }
  6517. /**
  6518. * Sets up default triggers for new users or upgraded users
  6519. *
  6520. * @param int $userid ID of the user
  6521. * @return bool TRUE on success, FALSE if not
  6522. * @author Kieran Hogg
  6523. */
  6524. function setup_user_triggers($userid)
  6525. {
  6526. $return = TRUE;
  6527. $userid = intval($userid);
  6528. if ($userid != 0)
  6529. {
  6530. $sqls[] = "INSERT INTO `{$GLOBALS['dbTriggers']}` (`triggerid`, `userid`, `action`, `template`, `parameters`, `checks`)
  6531. VALUES('TRIGGER_INCIDENT_ASSIGNED', {$userid}, 'ACTION_NOTICE', 'NOTICE_INCIDENT_ASSIGNED', '', '{userid} == {$userid}');";
  6532. $sqls[] = "INSERT INTO `{$GLOBALS['dbTriggers']}` (`triggerid`, `userid`, `action`, `template`, `parameters`, `checks`)
  6533. VALUES('TRIGGER_SIT_UPGRADED', {$userid}, 'ACTION_NOTICE', 'NOTICE_SIT_UPGRADED', '', '');";
  6534. $sqls[] = "INSERT INTO `{$GLOBALS['dbTriggers']}` (`triggerid`, `userid`, `action`, `template`, `parameters`, `checks`)
  6535. VALUES('TRIGGER_INCIDENT_CLOSED', {$userid}, 'ACTION_NOTICE', 'NOTICE_INCIDENT_CLOSED', '', '{userid} == {$userid}');";
  6536. $sqls[] = "INSERT INTO `{$GLOBALS['dbTriggers']}` (`triggerid`, `userid`, `action`, `template`, `parameters`, `checks`)
  6537. VALUES('TRIGGER_INCIDENT_NEARING_SLA', {$userid}, 'ACTION_NOTICE', 'NOTICE_INCIDENT_NEARING_SLA', '',
  6538. '{ownerid} == {$userid} OR {townerid} == {$userid}');";
  6539. $sqls[] = "INSERT INTO `{$GLOBALS['dbTriggers']}` (`triggerid`, `userid`, `action`, `template`, `parameters`, `checks`)
  6540. VALUES('TRIGGER_LANGUAGE_DIFFERS', {$userid}, 'ACTION_NOTICE', 'NOTICE_LANGUAGE_DIFFERS', '', '');";
  6541. foreach ($sqls AS $sql)
  6542. {
  6543. mysql_query($sql);
  6544. if (mysql_error())
  6545. {
  6546. trigger_error("MySQL Query Error ".mysql_error(), E_USER_ERROR);
  6547. $return = FALSE;
  6548. }
  6549. }
  6550. }
  6551. else
  6552. {
  6553. trigger_error("setup_user_triggers() Invalid userid '{$userid}' specified", E_USER_NOTICE);
  6554. $return = FALSE;
  6555. }
  6556. return $return;
  6557. }
  6558. /**
  6559. * Returns the SLA ID of a contract
  6560. *
  6561. * @param int $maintid ID of the contract
  6562. * @return int ID of the SLA
  6563. * @author Kieran Hogg
  6564. */
  6565. function contract_slaid($maintid)
  6566. {
  6567. $maintid = intval($maintid);
  6568. $slaid = db_read_column('servicelevelid', $GLOBALS['dbMaintenance'], $maintid);
  6569. return $slaid;
  6570. }
  6571. /**
  6572. * Returns the salesperson ID of a site
  6573. *
  6574. * @param int $siteid ID of the site
  6575. * @return int ID of the salesperson
  6576. * @author Kieran Hogg
  6577. */
  6578. function site_salespersonid($siteid)
  6579. {
  6580. $siteid = intval($siteid);
  6581. $salespersonid = db_read_column('owner', $GLOBALS['dbSites'], $siteid);
  6582. return $salespersonid;
  6583. }
  6584. /**
  6585. * Returns the salesperson's name of a site
  6586. *
  6587. * @param int $siteid ID of the site
  6588. * @return string name of the salesperson
  6589. * @author Kieran Hogg
  6590. */
  6591. function site_salesperson($siteid)
  6592. {
  6593. $siteid = intval($siteid);
  6594. $salespersonid = db_read_column('owner', $GLOBALS['dbSites'], $siteid);
  6595. return user_realname($salespersonid);
  6596. }
  6597. /**
  6598. * Function to return currently running SiT! version
  6599. * @return String - Currently running application version
  6600. */
  6601. function application_version_string()
  6602. {
  6603. global $application_version_string;
  6604. return $application_version_string;
  6605. }
  6606. /**
  6607. * Returns the currently running schema version
  6608. * @author Paul Heaney
  6609. * @return String - currently running schema version
  6610. */
  6611. function database_schema_version()
  6612. {
  6613. $return = '';
  6614. $sql = "SELECT `schemaversion` FROM `{$GLOBALS['dbSystem']}` WHERE id = 0";
  6615. $result = mysql_query($sql);
  6616. if (mysql_error())
  6617. {
  6618. trigger_error("MySQL Query Error ".mysql_error(), E_USER_WARNING);
  6619. $return = FALSE;
  6620. }
  6621. if (mysql_num_rows($result) > 0)
  6622. {
  6623. list($return) = mysql_fetch_row($result);
  6624. }
  6625. return $return;
  6626. }
  6627. /**
  6628. * Returns the contacts's portal username
  6629. *
  6630. * @param int $userid ID of the contact
  6631. * @return string username
  6632. * @author Kieran Hogg
  6633. */
  6634. function contact_username($userid)
  6635. {
  6636. $userid = intval($userid);
  6637. return db_read_column('username', $GLOBALS['dbContacts'], $userid);
  6638. }
  6639. /**
  6640. * Populates $_SESSION['syslang], system language strings
  6641. *
  6642. * @author Kieran Hogg
  6643. */
  6644. function populate_syslang()
  6645. {
  6646. global $CONFIG;
  6647. // Populate $SYSLANG with system lang
  6648. $file = APPLICATION_I18NPATH . "{$CONFIG['default_i18n']}.inc.php";
  6649. if (file_exists($file))
  6650. {
  6651. $fh = fopen($file, "r");
  6652. $theData = fread($fh, filesize($file));
  6653. fclose($fh);
  6654. $lines = explode("\n", $theData);
  6655. foreach ($lines as $values)
  6656. {
  6657. $badchars = array("$", "\"", "\\", "<?php", "?>");
  6658. $values = trim(str_replace($badchars, '', $values));
  6659. if (substr($values, 0, 3) == "str")
  6660. {
  6661. $vars = explode("=", $values);
  6662. $vars[0] = trim($vars[0]);
  6663. $vars[1] = trim(substr_replace($vars[1], "",-2));
  6664. $vars[1] = substr_replace($vars[1], "",0, 1);
  6665. $SYSLANG[$vars[0]] = $vars[1];
  6666. }
  6667. }
  6668. $_SESSION['syslang'] = $SYSLANG;
  6669. }
  6670. else
  6671. {
  6672. trigger_error("File specified in \$CONFIG['default_i18n'] can't be found", E_USER_ERROR);
  6673. }
  6674. }
  6675. /**
  6676. * Outputs a contact's contract associate, if the viewing user is allowed
  6677. * @author Kieran Hogg
  6678. * @param int $userid ID of the contact
  6679. * @return string output html
  6680. * @todo TODO should this be renamed, it has nothing to do with users
  6681. */
  6682. function user_contracts_table($userid, $mode = 'internal')
  6683. {
  6684. global $now, $CONFIG, $sit;
  6685. if ((!empty($sit[2]) AND user_permission($sit[2], 30)
  6686. OR ($_SESSION['usertype'] == 'admin'))) // view supported products
  6687. {
  6688. $html .= "<h4>".icon('contract', 16)." {$GLOBALS['strContracts']}:</h4>";
  6689. // Contracts we're explicit supported contact for
  6690. $sql = "SELECT sc.maintenanceid AS maintenanceid, m.product, p.name AS productname, ";
  6691. $sql .= "m.expirydate, m.term ";
  6692. $sql .= "FROM `{$GLOBALS['dbContacts']}` AS c, ";
  6693. $sql .= "`{$GLOBALS['dbSupportContacts']}` AS sc, ";
  6694. $sql .= "`{$GLOBALS['dbMaintenance']}` AS m, ";
  6695. $sql .= "`{$GLOBALS['dbProducts']}` AS p ";
  6696. $sql .= "WHERE c.id = '{$userid}' ";
  6697. $sql .= "AND (sc.maintenanceid=m.id AND sc.contactid='$userid') ";
  6698. $sql .= "AND m.product=p.id ";
  6699. // Contracts we're an 'all supported' on
  6700. $sql .= "UNION ";
  6701. $sql .= "SELECT m.id AS maintenanceid, m.product, p.name AS productname, ";
  6702. $sql .= "m.expirydate, m.term ";
  6703. $sql .= "FROM `{$GLOBALS['dbContacts']}` AS c, ";
  6704. $sql .= "`{$GLOBALS['dbMaintenance']}` AS m, ";
  6705. $sql .= "`{$GLOBALS['dbProducts']}` AS p ";
  6706. $sql .= "WHERE c.id = '{$userid}' AND c.siteid = m.site ";
  6707. $sql .= "AND m.allcontactssupported = 'yes' ";
  6708. $sql .= "AND m.product=p.id ";
  6709. $result = mysql_query($sql);
  6710. if (mysql_error()) trigger_error("MySQL Query Error ".mysql_error(), E_USER_WARNING);
  6711. if (mysql_num_rows($result)>0)
  6712. {
  6713. $html .= "<table align='center' class='vertical'>";
  6714. $html .= "<tr>";
  6715. $html .= "<th>{$GLOBALS['strID']}</th><th>{$GLOBALS['strProduct']}</th><th>{$GLOBALS['strExpiryDate']}</th>";
  6716. $html .= "</tr>\n";
  6717. $supportcount=1;
  6718. $shade='shade2';
  6719. while ($supportedrow = mysql_fetch_array($result))
  6720. {
  6721. if ($supportedrow['term'] == 'yes')
  6722. {
  6723. $shade='expired';
  6724. }
  6725. if ($supportedrow['expirydate'] < $now AND $supportedrow['expirydate'] != -1)
  6726. {
  6727. $shade='expired';
  6728. }
  6729. $html .= "<tr><td class='$shade'>";
  6730. $html .= ''.icon('contract', 16)." ";
  6731. if ($mode == 'internal')
  6732. {
  6733. $html .= "<a href='contract_details.php?id=";
  6734. }
  6735. else
  6736. {
  6737. $html .= "<a href='contracts.php?id=";
  6738. }
  6739. $html .= "{$supportedrow['maintenanceid']}'>";
  6740. $html .= "{$GLOBALS['strContract']}: ";
  6741. $html .= "{$supportedrow['maintenanceid']}</a></td>";
  6742. $html .= "<td class='$shade'>{$supportedrow['productname']}</td>";
  6743. $html .= "<td class='$shade'>";
  6744. if ($supportedrow['expirydate'] == -1)
  6745. {
  6746. $html .= $GLOBALS['strUnlimited'];
  6747. }
  6748. else
  6749. {
  6750. $html .= ldate($CONFIG['dateformat_date'], $supportedrow['expirydate']);
  6751. }
  6752. if ($supportedrow['term'] == 'yes')
  6753. {
  6754. $html .= " {$GLOBALS['strTerminated']}";
  6755. }
  6756. $html .= "</td>";
  6757. $html .= "</tr>\n";
  6758. $supportcount++;
  6759. $shade = 'shade2';
  6760. }
  6761. $html .= "</table>\n";
  6762. }
  6763. else
  6764. {
  6765. $html .= "<p align='center'>{$GLOBALS['strNone']}</p>\n";
  6766. }
  6767. if ($mode == 'internal')
  6768. {
  6769. $html .= "<p align='center'>";
  6770. $html .= "<a href='contract_add_contact.php?contactid={$userid}&amp;context=contact'>";
  6771. $html .= "{$GLOBALS['strAssociateContactWithContract']}</a></p>\n";
  6772. }
  6773. }
  6774. return $html;
  6775. }
  6776. // -------------------------- // -------------------------- // --------------------------
  6777. // leave this section at the bottom of functions.inc.php ================================
  6778. // Evaluate and Load plugins
  6779. if (is_array($CONFIG['plugins']))
  6780. {
  6781. foreach ($CONFIG['plugins'] AS $plugin)
  6782. {
  6783. // Remove any dots
  6784. $plugin = str_replace('.','',$plugin);
  6785. // Remove any slashes
  6786. $plugin = str_replace('/','',$plugin);
  6787. $plugini18npath = APPLICATION_PLUGINPATH . "{$plugin}". DIRECTORY_SEPARATOR . "i18n". DIRECTORY_SEPARATOR;
  6788. if ($plugin != '')
  6789. {
  6790. if (file_exists(APPLICATION_PLUGINPATH . "{$plugin}.php"))
  6791. {
  6792. include (APPLICATION_PLUGINPATH . "{$plugin}.php");
  6793. // Load i18n if it exists
  6794. if (file_exists($plugini18npath))
  6795. {
  6796. @include ("{$plugini18npath}{$CONFIG['default_i18n']}.inc.php");
  6797. if (!empty($_SESSION['lang'])
  6798. AND $_SESSION['lang'] != $CONFIG['default_i18n'])
  6799. {
  6800. @include ("{$plugini18npath}{$_SESSION['lang']}.inc.php");
  6801. }
  6802. }
  6803. }
  6804. else
  6805. {
  6806. trigger_error("Plugin '{$plugin}' could not be found.", E_USER_WARNING);
  6807. }
  6808. }
  6809. }
  6810. }
  6811. /**
  6812. * Register a plugin context handler function
  6813. * @author Ivan Lucas
  6814. * @param string $context - A valid plugin context
  6815. * @param string $action - Your plugin context handler function name
  6816. * @note see http://sitracker.org/wiki/CreatingPlugins for help and a list
  6817. * of contexts
  6818. */
  6819. function plugin_register($context, $action)
  6820. {
  6821. global $PLUGINACTIONS;
  6822. $PLUGINACTIONS[$context][] = $action;
  6823. }
  6824. /**
  6825. * Call a plugin function that handles a given context
  6826. * @author Ivan Lucas
  6827. * @param string $context - Plugin context,
  6828. * @param string $optparms - Optional parameters
  6829. * @return mixed - Whatever the plugin function returns
  6830. * @note This function calls a plugin function or multiple plugin
  6831. * functions, if they exist.
  6832. * see http://sitracker.org/wiki/CreatingPlugins for help and a list
  6833. * of contexts
  6834. */
  6835. function plugin_do($context, $optparams = FALSE)
  6836. {
  6837. global $PLUGINACTIONS;
  6838. $rtnvalue = '';
  6839. if (is_array($PLUGINACTIONS[$context]))
  6840. {
  6841. foreach ($PLUGINACTIONS[$context] AS $action)
  6842. {
  6843. // Call Variable function (function with variable name)
  6844. if ($optparams)
  6845. {
  6846. $rtn = $action($optparams);
  6847. }
  6848. else
  6849. {
  6850. $rtn = $action();
  6851. }
  6852. // Append return value
  6853. if (is_array($rtn) AND is_array($rtnvalue))
  6854. {
  6855. array_push($rtnvalue, $rtn);
  6856. }
  6857. elseif (is_array($rtn) AND !is_array($rtnvalue))
  6858. {
  6859. $rtnvalue=array(); array_push($rtnvalue, $rtn);
  6860. }
  6861. else
  6862. {
  6863. $rtnvalue .= $rtn;
  6864. }
  6865. }
  6866. }
  6867. return $rtnvalue;
  6868. }
  6869. /**
  6870. * Function passed a day, month and year to identify if this day is defined as a public holiday
  6871. * @author Paul Heaney
  6872. * FIXME this is horribily inefficient, we should load a table ONCE with all the public holidays
  6873. and then just check that with this function
  6874. */
  6875. function is_day_bank_holiday($day, $month, $year)
  6876. {
  6877. global $dbHolidays;
  6878. $date = "{$year}-{$month}-{$day}";
  6879. $sql = "SELECT * FROM `{$dbHolidays}` WHERE type = 10 AND date = '{$date}'";
  6880. $result = mysql_query($sql);
  6881. if (mysql_error())
  6882. {
  6883. trigger_error(mysql_error(),E_USER_ERROR);
  6884. return FALSE;
  6885. }
  6886. if (mysql_num_rows($result) > 0) return TRUE;
  6887. else return FALSE;
  6888. }
  6889. /**
  6890. * Outputs a table or csv file based on csv-based array
  6891. * @author Kieran Hogg
  6892. * @param array $data Array of data, see @note for format
  6893. * @param string $ouput Whether to show a table or create a csv file
  6894. * @return string $html The html to produce the output
  6895. * @note format: $array[] = 'Colheader1,Colheader2'; $array[] = 'data1,data2';
  6896. */
  6897. function create_report($data, $output = 'table', $filename = 'report.csv')
  6898. {
  6899. if ($output == 'table')
  6900. {
  6901. $html = "\n<table align='center'><tr>\n";
  6902. $data = explode("\n", $data);
  6903. $headers = explode(',', $data[0]);
  6904. $rows = sizeof($headers);
  6905. foreach ($headers as $header)
  6906. {
  6907. $html .= colheader($header, $header);
  6908. }
  6909. $html .= "</tr>";
  6910. if (sizeof($data) == 1)
  6911. {
  6912. $html .= "<tr><td rowspan='{$rows}'>{$GLOBALS['strNoRecords']}</td></tr>";
  6913. }
  6914. else
  6915. {
  6916. // use 1 -> sizeof as we've already done one row
  6917. for ($i = 1; $i < sizeof($data); $i++)
  6918. {
  6919. $html .= "<tr>";
  6920. $values = explode(',', $data[$i]);
  6921. foreach ($values as $value)
  6922. {
  6923. $html .= "<td>$value</td>";
  6924. }
  6925. $html .= "</tr>";
  6926. }
  6927. }
  6928. $html .= "</table>";
  6929. }
  6930. else
  6931. {
  6932. $html = header("Content-type: text/csv\r\n");
  6933. $html .= header("Content-disposition-type: attachment\r\n");
  6934. $html .= header("Content-disposition: filename={$filename}");
  6935. foreach($data as $line)
  6936. {
  6937. if (!beginsWith($line, "\""))
  6938. {
  6939. $line = "\"".str_replace(",", "\",\"",$line)."\"\r\n";
  6940. }
  6941. $html .= $line;
  6942. }
  6943. }
  6944. return $html;
  6945. }
  6946. /**
  6947. * HTML for an alphabetical index of links
  6948. * @author Ivan Lucas
  6949. * @param string $baseurl start of a URL, the letter will be appended to this
  6950. * @return HTML
  6951. */
  6952. function alpha_index($baseurl = '#')
  6953. {
  6954. global $i18nAlphabet;
  6955. $html = '';
  6956. if (!empty($i18nAlphabet))
  6957. {
  6958. $len = utf8_strlen($i18nAlphabet);
  6959. for ($i = 0; $i < $len; $i++)
  6960. {
  6961. $html .= "<a href=\"{$baseurl}";
  6962. $html .= urlencode(utf8_substr($i18nAlphabet, $i, 1))."\">";
  6963. $html .= utf8_substr($i18nAlphabet, $i, 1)."</a> | \n";
  6964. }
  6965. }
  6966. return $html;
  6967. }
  6968. /**
  6969. * Converts emoticon text to HTML
  6970. * @author Kieran Hogg
  6971. * @param string $text. Text with smileys in it
  6972. * @return string HTML
  6973. */
  6974. function emoticons($text)
  6975. {
  6976. global $CONFIG;
  6977. $smiley_url = "{$CONFIG['application_uriprefix']}{$CONFIG['application_webpath']}images/emoticons/";
  6978. $smiley_regex = array(0 => "/\:[-]?\)/s",
  6979. 1 => "/\:[-]?\(/s",
  6980. 2 => "/\;[-]?\)/s",
  6981. 3 => "/\:[-]?[pP]/s",
  6982. 4 => "/\:[-]?@/s",
  6983. 5 => "/\:[-]?[Oo]/s",
  6984. 6 => "/\:[-]?\\$/s",
  6985. 7 => "/\\([Yy]\)/s",
  6986. 8 => "/\\([Nn]\)/s",
  6987. 9 => "/\\([Bb]\)/s",
  6988. 10 => "/\:[-]?[dD]/s"
  6989. );
  6990. $smiley_replace = array(0 => "<img src='{$smiley_url}smile.png' alt='$1' title='$1' />",
  6991. 1 => "<img src='{$smiley_url}sad.png' alt='$1' title='$1' />",
  6992. 2 => "<img src='{$smiley_url}wink.png' alt='$1' title='$1' />",
  6993. 3 => "<img src='{$smiley_url}tongue.png' alt='$1' title='$1' />",
  6994. 4 => "<img src='{$smiley_url}angry.png' alt='$1' title='$1' />",
  6995. 5 => "<img src='{$smiley_url}omg.png' alt='$1' title='$1' />",
  6996. 6 => "<img src='{$smiley_url}embarassed.png' alt='$1' title='$1' />",
  6997. 7 => "<img src='{$smiley_url}thumbs_up.png' alt='$1' title='$1' />",
  6998. 8 => "<img src='{$smiley_url}thumbs_down.png' alt='$1' title='$1' />",
  6999. 9 => "<img src='{$smiley_url}beer.png' alt='$1' title='$1' />",
  7000. 10 => "<img src='{$smiley_url}teeth.png' alt='$1' title='$1' />"
  7001. );
  7002. $html = preg_replace($smiley_regex, $smiley_replace, $text);
  7003. return $html;
  7004. }
  7005. /**
  7006. * Inserts a new incident update
  7007. * @param int $incidentid ID of the incident to add the update to
  7008. * @param string $text The text of the update
  7009. * @param enum $type (Optional) Update type (Default: 'default'), types:
  7010. * 'default', 'editing', 'opening', 'email', 'reassigning', 'closing',
  7011. * 'reopening', 'auto', 'phonecallout', 'phonecallin', 'research', 'webupdate',
  7012. * 'emailout', 'emailin', 'externalinfo', 'probdef', 'solution', 'actionplan',
  7013. * 'slamet', 'reviewmet', 'tempassigning', 'auto_chase_email',
  7014. * 'auto_chase_phone', 'auto_chase_manager', 'auto_chased_phone',
  7015. * 'auto_chased_manager', 'auto_chase_managers_manager',
  7016. * 'customerclosurerequest', 'fromtask'
  7017. * @param string $sla The SLA the update meets
  7018. * @param int $userid (Optional) ID of the user doing the updating (Default: 0)
  7019. * @param int $currentowner (Optional) ID of the current incident owner
  7020. * @param int $currentstatus (Optional) Current incident status (Default: 1 = active)
  7021. * @param enum $visibility (Optional) Whether to 'show' or 'hide' in the portal (Default: 'show')
  7022. * @author Kieran Hogg
  7023. */
  7024. function new_update($incidentid, $text, $type = 'default', $sla = '', $userid = 0, $currentowner = '',
  7025. $currentstatus = 1, $visibility = 'show')
  7026. {
  7027. global $now;
  7028. $text = cleanvar($text);
  7029. $sql = "INSERT INTO `{$GLOBALS['dbUpdates']}` (incidentid, userid, ";
  7030. $sql .= "type, bodytext, timestamp, currentowner, currentstatus, ";
  7031. $sql .= "customervisibility, sla) VALUES ('{$incidentid}', '{$userid}', ";
  7032. $sql .= "'{$type}', '{$text}', '{$now}', '{$currentowner}', ";
  7033. $sql .= "'{$currentstatus}', '{$visibility}', '{$sla}')";
  7034. $result = mysql_query($sql);
  7035. if (mysql_error())
  7036. {
  7037. trigger_error("MySQL Query Error ".mysql_error(), E_USER_ERROR);
  7038. return FALSE;
  7039. }
  7040. else
  7041. {
  7042. return mysql_insert_id();
  7043. }
  7044. }
  7045. /**
  7046. * Create a new holding queue item
  7047. * @param int $updateid ID of the associated update entry
  7048. * @param string $from Name of the from field
  7049. * @param string $subject Subject of the item
  7050. * @param string $emailfrom Email address the item is from
  7051. * @param int $contactid (Optional) Contact ID of the sender
  7052. * @param int $incidentid (Optional) Associated incident ID
  7053. * @param int $locked (Optional) 1 if the item is locked, 0 if not
  7054. * @param time $lockeduntil (Optional) MySQL timestamp of lock expiration
  7055. * @param string $reason (Optional) Reason the item is in the holding queue
  7056. * @param id $reason_user (Optional) The user ID who set the reason
  7057. * @param time $reason_time (Optional) MySQL timestamp of when the reason was set
  7058. * @author Kieran Hogg
  7059. */
  7060. function create_temp_incoming($updateid, $from, $subject, $emailfrom,
  7061. $contactid = '', $incidentid = 0, $locked = '',
  7062. $lockeduntil = '', $reason = '',
  7063. $reason_user = '', $reason_time = '')
  7064. {
  7065. global $dbTempIncoming;
  7066. $sql = "INSERT INTO `{$dbTempIncoming}`(updateid, `from`, subject, ";
  7067. $sql .= "emailfrom, contactid, incidentid, locked, lockeduntil, ";
  7068. $sql .= "reason, reason_user, reason_time) VALUES('{$updateid}', ";
  7069. $sql .= "'{$from}', '{$subject}', '{$emailfrom}', '{$contactid}', ";
  7070. $sql .= "'{$incidentid}', '{$locked}', '{$lockeduntil}', '{$reason}', ";
  7071. $sql .= "'{$reason_user}', '{$reason_time}')";
  7072. $result = mysql_query($sql);
  7073. if (mysql_error())
  7074. {
  7075. trigger_error("MySQL Query Error ".mysql_error(), E_USER_ERROR);
  7076. return FALSE;
  7077. }
  7078. else
  7079. {
  7080. return mysql_insert_id();
  7081. }
  7082. }
  7083. /**
  7084. * Detect whether an array is associative
  7085. * @param array $array
  7086. * @note From http://uk.php.net/manual/en/function.is-array.php#77744
  7087. */
  7088. function is_assoc($array)
  7089. {
  7090. return is_array($array) && count($array) !== array_reduce(array_keys($array), 'is_assoc_callback', 0);
  7091. }
  7092. /**
  7093. * Detect whether an array is associative
  7094. * @param various $a
  7095. * @param various $b
  7096. * @note Callback function, Called by is_assoc()
  7097. From http://uk.php.net/manual/en/function.is-array.php#77744
  7098. **/
  7099. function is_assoc_callback($a, $b)
  7100. {
  7101. return $a === $b ? $a + 1 : 0;
  7102. }
  7103. /**
  7104. * HTML for a config variable input box
  7105. * @author Ivan Lucas
  7106. * @param string $setupvar The setup variable key name
  7107. * @param bool $showvarnames Whether to display the config variable name
  7108. * @returns string HTML
  7109. */
  7110. function cfgVarInput($setupvar, $showvarnames = FALSE)
  7111. {
  7112. global $CONFIG, $CFGVAR;
  7113. if ($CFGVAR[$setupvar]['type'] == 'languageselect'
  7114. OR $CFGVAR[$setupvar]['type'] == 'languagemultiselect')
  7115. {
  7116. $available_languages = available_languages();
  7117. }
  7118. $html .= "<div class='configvar'>";
  7119. if ($CFGVAR[$setupvar]['title']!='') $title = $CFGVAR[$setupvar]['title'];
  7120. else $title = $setupvar;
  7121. $html .= "<h4>{$title}</h4>";
  7122. if ($CFGVAR[$setupvar]['help']!='') $html .= "<p class='helptip'>{$CFGVAR[$setupvar]['help']}</p>\n";
  7123. $value = '';
  7124. if (!$cfg_file_exists OR ($cfg_file_exists AND $cfg_file_writable))
  7125. {
  7126. $value = $CONFIG[$setupvar];
  7127. if (is_bool($value))
  7128. {
  7129. if ($value==TRUE) $value='TRUE';
  7130. else $value='FALSE';
  7131. }
  7132. elseif (is_array($value))
  7133. {
  7134. if (is_assoc($value))
  7135. {
  7136. $value = "array(".implode_assoc('=>',',',$value).")";
  7137. }
  7138. else
  7139. {
  7140. $value="array(".implode(',',$value).")";
  7141. }
  7142. }
  7143. if ($setupvar=='db_password' AND $_REQUEST['action']!='reconfigure') $value='';
  7144. }
  7145. $value = stripslashes($value);
  7146. switch ($CFGVAR[$setupvar]['type'])
  7147. {
  7148. case 'select':
  7149. $html .= "<select name='{$setupvar}' id='{$setupvar}'>";
  7150. if (empty($CFGVAR[$setupvar]['options'])) $CFGVAR[$setupvar]['options'] = "TRUE|FALSE";
  7151. $options = explode('|', $CFGVAR[$setupvar]['options']);
  7152. foreach ($options AS $option)
  7153. {
  7154. $html .= "<option value=\"{$option}\"";
  7155. if ($option == $value) $html .= " selected='selected'";
  7156. $html .= ">{$option}</option>\n";
  7157. }
  7158. $html .= "</select>";
  7159. break;
  7160. case 'percent':
  7161. $html .= "<select name='{$setupvar}' id='{$setupvar}'>";
  7162. for($i = 0; $i <= 100; $i++)
  7163. {
  7164. $html .= "<option value=\"{$i}\"";
  7165. if ($i == $value) $html .= " selected='selected'";
  7166. $html .= ">{$i}</option>\n";
  7167. }
  7168. $html .= "</select>%";
  7169. break;
  7170. case 'interfacestyleselect':
  7171. $html .= interfacestyle_drop_down($setupvar, $value);
  7172. break;
  7173. case 'languageselect':
  7174. if (empty($value)) $value = $_SESSION['lang'];
  7175. $html .= array_drop_down($available_languages, $setupvar, $value, '', TRUE);
  7176. break;
  7177. case 'languagemultiselect':
  7178. if (empty($value))
  7179. {
  7180. foreach ($available_languages AS $code => $lang)
  7181. {
  7182. $value[] = $code;
  7183. }
  7184. $checked = TRUE;
  7185. }
  7186. else
  7187. {
  7188. $checked = FALSE;
  7189. $replace = array('array(', ')', "'");
  7190. $value = str_replace($replace, '', $value);
  7191. $value = explode(',', $value);
  7192. }
  7193. $html .= array_drop_down($available_languages, $setupvar, $value, '', TRUE, TRUE);
  7194. $attributes = "onchange=\"toggle_multiselect('{$setupvar}[]')\"";
  7195. $html .= "<label>".html_checkbox($setupvar.'checkbox', $checked, "");
  7196. $html .= $GLOBALS['strAll']."</label>";
  7197. break;
  7198. case 'slaselect':
  7199. $html .= serviceleveltag_drop_down($setupvar, $value, TRUE);
  7200. break;
  7201. case 'userselect':
  7202. $html .= user_drop_down($setupvar, $value, FALSE, FALSE, '', TRUE);
  7203. break;
  7204. case 'siteselect':
  7205. $html .= site_drop_down($setupvar, $value, FALSE);
  7206. break;
  7207. case 'userstatusselect':
  7208. $html .= userstatus_drop_down($setupvar, $value);
  7209. break;
  7210. case 'roleselect':
  7211. $html .= role_drop_down($setupvar, $value);
  7212. break;
  7213. case 'number':
  7214. $html .= "<input type='text' name='{$setupvar}' id='{$setupvar}' size='7' value=\"{$value}\" />";
  7215. break;
  7216. case '1darray':
  7217. $replace = array('array(', ')', "'");
  7218. $value = str_replace($replace, '', $value);
  7219. $html .= "<input type='text' name='{$setupvar}' id='{$setupvar}' size='60' value=\"{$value}\" />";
  7220. break;
  7221. case '2darray':
  7222. $replace = array('array(', ')', "'", '\r','\n');
  7223. $value = str_replace($replace, '', $value);
  7224. $value = str_replace(',', "\n", $value);
  7225. $html .= "<textarea name='{$setupvar}' id='{$setupvar}' cols='60' rows='10'>{$value}</textarea>";
  7226. break;
  7227. case 'password':
  7228. $html .= "<input type='password' id='cfg{$setupvar}' name='{$setupvar}' size='16' value=\"{$value}\" /> ".password_reveal_link("cfg{$setupvar}");
  7229. break;
  7230. case 'ldappassword':
  7231. $html .= "<input type='password' id='cfg{$setupvar}' name='{$setupvar}' size='16' value=\"{$value}\" /> ".password_reveal_link("cfg{$setupvar}");
  7232. $html.= " &nbsp; <a href='javascript:void(0);' onclick=\"checkLDAPDetails('status{$setupvar}');\">{$GLOBALS['strCheckLDAPDetails']}</a>";
  7233. break;
  7234. case 'text':
  7235. default:
  7236. if (strlen($CONFIG[$setupvar]) < 65)
  7237. {
  7238. $html .= "<input type='text' name='{$setupvar}' id='{$setupvar}' size='60' value=\"{$value}\" />";
  7239. }
  7240. else
  7241. {
  7242. $html .= "<textarea name='{$setupvar}' id='{$setupvar}' cols='60' rows='10'>{$value}</textarea>";
  7243. }
  7244. }
  7245. if (!empty($CFGVAR[$setupvar]['unit'])) $html .= " {$CFGVAR[$setupvar]['unit']}";
  7246. if (!empty($CFGVAR[$setupvar]['helplink'])) $html .= ' '.help_link($CFGVAR[$setupvar]['helplink']);
  7247. if ($setupvar == 'db_password' AND $_REQUEST['action'] != 'reconfigure' AND $value != '')
  7248. {
  7249. $html .= "<p class='info'>The current password setting is not shown</p>";
  7250. }
  7251. if ($showvarnames) $html .= "<br />(<var>\$CONFIG['$setupvar']</var>)";
  7252. if ($CFGVAR[$setupvar]['statusfield'] == 'TRUE')
  7253. {
  7254. $html .= "<div id='status{$setupvar}'></div>";
  7255. }
  7256. $html .= "</div>";
  7257. $html .= "<br />\n";
  7258. if ($c == 1) $c == 2;
  7259. else $c = 1;
  7260. return $html;
  7261. }
  7262. /**
  7263. * Save configuration
  7264. * @param array $setupvars. An array of setup variables $setupvars['setting'] = 'foo';
  7265. * @todo TODO, need to make setup.php use this INL 5Dec08
  7266. * @author Ivan Lucas
  7267. */
  7268. function cfgSave($setupvars)
  7269. {
  7270. global $dbConfig;
  7271. foreach ($setupvars AS $key => $value)
  7272. {
  7273. $sql = "REPLACE INTO `{$dbConfig}` (`config`, `value`) VALUES ('{$key}', '{$value}')";
  7274. mysql_query($sql);
  7275. if (mysql_error()) trigger_error(mysql_error(). " $sql",E_USER_WARNING);
  7276. }
  7277. return TRUE;
  7278. }
  7279. /**
  7280. * HTML for a hyperlink to hide/reveal a password field
  7281. * @author Ivan Lucas
  7282. */
  7283. function password_reveal_link($id)
  7284. {
  7285. $html = "<a href=\"javascript:password_reveal('$id')\" id=\"link{$id}\">{$GLOBALS['strReveal']}</a>";
  7286. return $html;
  7287. }
  7288. function holding_email_update_id($holding_email)
  7289. {
  7290. $holding_email = intval($holding_email);
  7291. return db_read_column('updateid', $GLOBALS['dbTempIncoming'], $holding_email);
  7292. }
  7293. function delete_holding_queue_update($updateid)
  7294. {
  7295. $sql = "DELETE FROM {$GLOBALS['dbTempIncoming']} WHERE updateid = '{$updateid}'";
  7296. mysql_query($sql);
  7297. if (mysql_error())
  7298. {
  7299. trigger_error(mysql_error(). " $sql",E_USER_WARNING);
  7300. return FALSE;
  7301. }
  7302. else
  7303. {
  7304. return TRUE;
  7305. }
  7306. }
  7307. function num_unread_emails()
  7308. {
  7309. global $dbTempIncoming;
  7310. $sql = "SELECT COUNT(*) AS count FROM `{$dbTempIncoming}`";
  7311. $result = mysql_query($sql);
  7312. if (mysql_error()) trigger_error(mysql_error(). " $sql",E_USER_WARNING);
  7313. list($count) = mysql_fetch_row($result);
  7314. return $count;
  7315. }
  7316. /**
  7317. * Checks whether an KB article exists and/or the user is allowed to view is
  7318. * @author Kieran Hogg
  7319. * @param $id int ID of the KB article
  7320. * @param $mode string 'public' for portal users, 'private' for internal users
  7321. * @return bool Whether we are allowed to see it or not
  7322. */
  7323. function is_kb_article($id, $mode)
  7324. {
  7325. $rtn = FALSE;
  7326. global $dbKBArticles;
  7327. $id = cleanvar($id);
  7328. if ($id > 0)
  7329. {
  7330. $sql = "SELECT distribution FROM `{$dbKBArticles}` ";
  7331. $sql .= "WHERE docid = '{$id}'";
  7332. $result = mysql_query($sql);
  7333. if (mysql_error()) trigger_error(mysql_error(). " $sql",E_USER_WARNING);
  7334. list($visibility) = mysql_fetch_row($result);
  7335. if ($visibility == 'public' && $mode == 'public')
  7336. {
  7337. $rtn = TRUE;
  7338. }
  7339. else if (($visibility == 'private' OR $visibility == 'restricted') AND
  7340. $mode == 'private')
  7341. {
  7342. $rtn = TRUE;
  7343. }
  7344. }
  7345. return $rtn;
  7346. }
  7347. // ** Place no more function defs below this **
  7348. // These are the modules that we are dependent on, without these something
  7349. // or everything will fail, so let's throw an error here.
  7350. // Check that the correct modules are loaded
  7351. if (!extension_loaded('mysql')) trigger_error('SiT requires the php/mysql module', E_USER_ERROR);
  7352. if (!extension_loaded('imap') AND $CONFIG['enable_inbound_mail'] == 'POP/IMAP')
  7353. {
  7354. trigger_error('SiT requires the php IMAP module to recieve incoming mail.'
  7355. .' If you really don\'t need this, you can set $CONFIG[\'enable_inbound_mail\'] to false');
  7356. }
  7357. if (version_compare(PHP_VERSION, "5.0.0", "<")) trigger_error('INFO: You are running an older PHP version, some features may not work properly.', E_USER_NOTICE);
  7358. if (@ini_get('register_globals') == 1 OR strtolower(@ini_get('register_globals')) == 'on')
  7359. {
  7360. trigger_error('Error: php.ini MUST have register_globals set to off, there are potential security risks involved with leaving it as it is!', E_USER_ERROR);
  7361. die('Stopping SiT now, fix your php and try again.');
  7362. }
  7363. ?>