PageRenderTime 111ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 2ms

/lib/functions.inc.php

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