PageRenderTime 89ms CodeModel.GetById 30ms RepoModel.GetById 2ms app.codeStats 0ms

/lib/bugtracking/int_jirasoap.php

https://bitbucket.org/pfernandez/testlink1.9.6
PHP | 468 lines | 273 code | 40 blank | 155 comment | 30 complexity | 56ec5fb6d7e2d08f3f8a61bbe477e01a MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, GPL-3.0
  1. <?php
  2. /**
  3. * TestLink Open Source Project - http://testlink.sourceforge.net/
  4. *
  5. * Filename $RCSfile: int_jirasoap.php,v $
  6. *
  7. * @version $Revision: 1.8 $
  8. * @modified $Date: 2010/03/16 08:33:40 $ $Author: amkhullar $
  9. *
  10. * @author amitkhullar <amkhullar@gmail.com>
  11. *
  12. * Integration with JIRA Using SOAP Interface.
  13. *
  14. * 20100316 - amitkhullar - BugID 3287
  15. *
  16. **/
  17. /** Interface name */
  18. define('BUG_INTERFACE_CLASSNAME',"jirasoapInterface");
  19. //set_error_handler("exception_error_handler", E_ALL);
  20. class jirasoapInterface extends bugtrackingInterface
  21. {
  22. var $dbHost = null;
  23. var $dbConnection = null;
  24. var $connected = false;
  25. var $dbCharSet = null;
  26. var $dbType = null;
  27. //members to connect through SOAP to the bugtracking information
  28. var $jiraUsername = BUG_TRACK_USERNAME;
  29. var $jiraPassword = BUG_TRACK_PASSWORD;
  30. var $baseURL = BUG_TRACK_HREF;
  31. //var $bugDetails = BUG_TRACK_DETAILS;
  32. var $soapURL = null;
  33. var $client = null;
  34. //Variables for storing the Jira Issue Values
  35. var $checkURL = false;
  36. protected $status_map = array();
  37. protected $issue = null;
  38. protected $issue_status = null;
  39. protected $issue_status_id = null;
  40. protected $issue_summary = null;
  41. protected $issue_due_date = null;
  42. /**
  43. * Constructor of bugtrackingInterface
  44. * put special initialization in here
  45. *
  46. * @version 1.0
  47. * @author amitkhullar <amkhullar@gmail.com>
  48. **/
  49. function jirasoapInterface()
  50. {
  51. $soapURL = $this->baseURL . BUG_TRACK_SOAP_HREF;
  52. $this->showBugURL = $this->baseURL . BUG_TRACK_SHOW_BUG_HREF;
  53. $this->enterBugURL = $this->baseURL . BUG_TRACK_ENTER_BUG_HREF;
  54. // Do nothing at constructor
  55. $checkURL = $this->is_valid_url(($this->soapURL));
  56. if (!$checkURL)
  57. {
  58. // Get all the status in JIRA
  59. $this->client = new soapclient($soapURL);
  60. $soap_token = $this->soap_login();
  61. $status = array();
  62. $status = $this->client->getStatuses($soap_token);
  63. foreach ($status as $key => $pair)
  64. {
  65. $this->status_map[$pair->name]=$pair->id;
  66. }
  67. }
  68. else
  69. {
  70. tLog('Connect to Bug Tracker URL fails!!! ', 'ERROR');
  71. }
  72. }
  73. /**
  74. * establishes the soap connection and logins to the
  75. * bugtracking system
  76. *
  77. * @return token if the login was succesful
  78. *
  79. * @version 1.0
  80. * @author amitkhullar <amkhullar@gmail.com>
  81. **/
  82. function soap_login()
  83. {
  84. try
  85. {
  86. $token = $this->client->login($this->jiraUsername, $this->jiraPassword);
  87. return $token;
  88. }
  89. catch (Exception $e)
  90. {
  91. tLog($e->getMessage(), 'WARNING');
  92. }
  93. }
  94. /**
  95. * establishes the soap connection to the bugtracking system
  96. *
  97. * @return null if issue not found
  98. * value 'issue_status_id' if jira_summary is false
  99. * value 'issue_status_id','issue_summary','issue_due_date' if jira_summary is true
  100. *
  101. * @version 1.0
  102. * @author amitkhullar <amkhullar@gmail.com>
  103. **/
  104. function soap_request($jira_key=null, $jira_summary = false)
  105. {
  106. try
  107. {
  108. $return_var = null;
  109. $soap_token = $this->soap_login();
  110. if (!is_null($jira_key)) // Perform the Get Issue operation
  111. {
  112. $issue = $this->client->getIssue($soap_token, $jira_key);
  113. if (!is_null($issue))
  114. {
  115. $issue_status_id = $issue->status;
  116. $issue_summary = $issue->summary;
  117. $issue_due_date = !is_null($issue->duedate)? ($issue->duedate): null;
  118. if ($jira_summary )// If jira_summary is true return the fileds below
  119. {
  120. return compact('issue_status_id','issue_summary', 'issue_due_date');
  121. }
  122. elseif ($issue_status_id) // else just return the issue status id
  123. {
  124. return $issue_status_id;
  125. }
  126. }
  127. else
  128. {
  129. return $return_var; //Issue not found so return null
  130. }
  131. }
  132. }
  133. catch (Exception $e)
  134. {
  135. tLog($jira_key . "-" . $e->getMessage(), 'WARNING');
  136. }
  137. }
  138. /**
  139. * establishes the soap connection to the bugtracking system
  140. *
  141. * @return bool returns true if the soap connection was established and the
  142. * wsdl could be downloaded, false else
  143. *
  144. * @version 1.0
  145. * @author amitkhullar <amkhullar@gmail.com>
  146. **/
  147. function connect()
  148. {
  149. $this->connected = true;
  150. return $this->connected;
  151. }
  152. /**
  153. * returns state of the soap connection
  154. *
  155. * @return bool true if the soap connection is established, false else
  156. *
  157. * @version 1.0
  158. * @author amitkhullar <amkhullar@gmail.com>
  159. **/
  160. function isConnected()
  161. {
  162. return $this->connected;
  163. }
  164. /**
  165. * closes the soap connection (if any)
  166. *
  167. * @version 1.0
  168. * @author amitkhullar <amkhullar@gmail.com>
  169. **/
  170. function disconnect()
  171. {
  172. $this->connected = false;
  173. }
  174. /**
  175. * Return the URL to the bugtracking page for viewing
  176. * the bug with the given id.
  177. *
  178. * @param int id the bug id
  179. *
  180. * @return string returns a complete URL to view the bug
  181. *
  182. **/
  183. function buildViewBugURL($id)
  184. {
  185. return ($this->showBugURL.$id);
  186. }
  187. /**
  188. * Returns the status in a readable form (HTML context) for the bug with the given id
  189. *
  190. * @param int id the bug id
  191. *
  192. * @return string returns the status (in a readable form) of the given bug if the bug
  193. * was found, else false
  194. *
  195. * @version 1.0
  196. * @author amitkhullar <amkhullar@gmail.com>
  197. **/
  198. function getBugStatusString($id)
  199. {
  200. $status_desc = null;
  201. $jira_id = $this->soap_request($id);
  202. //if the bug wasn't found the status is null else we simply display the bugID with status
  203. if (!is_null($jira_id))
  204. {
  205. $status_desc = array_search($jira_id, $this->status_map);
  206. if (strcasecmp($status_desc, 'closed') == 0 || strcasecmp($status_desc, 'resolved') == 0 )
  207. {
  208. $status_desc = "<del>" . $status_desc . "</del>";
  209. }
  210. $status_desc = "<b>" . $id . ": </b>[" . $status_desc . "] " ;
  211. }
  212. else
  213. {
  214. $status_desc = "The BUG Id-".$id." does not exist in BTS";
  215. }
  216. return $status_desc;
  217. }
  218. /**
  219. * default implementation for fetching the bug summary from the
  220. * bugtracking system
  221. *
  222. * @param int id the bug id
  223. *
  224. * @return string returns the bug summary (if bug is found), or false
  225. *
  226. * @version 1.0
  227. * @author amitkhullar <amkhullar@gmail.com>
  228. **/
  229. function getBugSummaryString($id)
  230. {
  231. $summary_string = "Error: Summary not found in JIRA for Ticket#$id";
  232. $jira_summary = $this->soap_request($id,TRUE);
  233. if (!is_null($jira_summary))
  234. {
  235. extract($jira_summary);
  236. $summary_string = $issue_summary;
  237. $due_date = $this->parse_date($issue_due_date);
  238. $summary_string = $summary_string . '<b> [' . $due_date . ']</b> ';
  239. }
  240. return $summary_string;
  241. }
  242. /**
  243. * returns the URL which should be displayed for entering bugs
  244. *
  245. * @return string returns a complete URL
  246. *
  247. * @version 1.0
  248. * @author amitkhullar <amkhullar@gmail.com>
  249. **/
  250. function parse_date($due_date)
  251. {
  252. if (!is_null($due_date))
  253. {
  254. $due_date = date_parse($due_date);
  255. $due_date = ((gmmktime(0, 0, 0, $due_date['month'], $due_date['day'], $due_date['year'])));
  256. $due_date = gmstrftime("%d %b %Y",($due_date));
  257. return $due_date ;
  258. }
  259. else
  260. {
  261. return "No Date";
  262. }
  263. }
  264. /**
  265. * returns the URL which should be displayed for entering bugs
  266. *
  267. * @return string returns a complete URL
  268. *
  269. * @version 1.0
  270. * @author amitkhullar <amkhullar@gmail.com>
  271. **/
  272. function getEnterBugURL()
  273. {
  274. return $this->enterBugURL;
  275. }
  276. /**
  277. * default implementation for generating a link to the bugtracking page for viewing
  278. * the bug with the given id in a new page
  279. *
  280. * @param int id the bug id
  281. *
  282. * @return string returns a complete URL to view the bug (if found in db)
  283. *
  284. * @version 1.0
  285. * @author Toshiyuki Kawanishi
  286. * @since 1.8 RC 3
  287. **/
  288. function buildViewBugLink($bugID,$bWithSummary = false)
  289. {
  290. global $tlCfg;
  291. $link = "<a href='" .$this->buildViewBugURL($bugID) . "' target='_blank'>";
  292. $status = $this->getBugStatusString($bugID);
  293. if (!is_null($status))
  294. {
  295. $link .= $status;
  296. }
  297. else
  298. {
  299. $link .= $bugID;
  300. }
  301. if ($bWithSummary)
  302. {
  303. $summary = $this->getBugSummaryString($bugID);
  304. if (!is_null($summary))
  305. {
  306. $link .= " - " . $summary;
  307. }
  308. }
  309. $link .= "</a>";
  310. return $link;
  311. }
  312. /**
  313. * checks a bug id for validity
  314. *
  315. * @return bool returns true if the bugid has the right format, false else
  316. **/
  317. function checkBugID($id)
  318. {
  319. $status_ok = true;
  320. if(trim($id) == "")
  321. {
  322. $status_ok = false;
  323. }
  324. if($status_ok)
  325. {
  326. $forbidden_chars = '/[!|?%&()\/=?]/';
  327. if (preg_match($forbidden_chars, $id))
  328. {
  329. $status_ok = false;
  330. }
  331. }
  332. return $status_ok;
  333. }
  334. /**
  335. * Overloaded function checks a bug id for existence
  336. *
  337. * @return bool returns true if the bugid exists, false else
  338. **/
  339. function checkBugID_existence($id)
  340. {
  341. $status_ok = 1; //BUG 3287
  342. $status = $this->checkBugID($id);
  343. if ($status)
  344. {
  345. $issue_exists = $this->getBugStatusString($id);
  346. if (!is_null($issue_exists))
  347. {
  348. if ((stristr($issue_exists, "does not exist") == TRUE))
  349. {
  350. $status_ok = 0;
  351. }
  352. }
  353. }
  354. return $status_ok;
  355. }
  356. /**
  357. * this function establishes the checks if the url is valid
  358. *
  359. * @return bool returns true if the connection was established,
  360. * else false
  361. *
  362. * @version 1.0
  363. * @author amitkhullar <amkhullar@gmail.com>
  364. **/
  365. function is_valid_url($url)
  366. {
  367. $url = @parse_url($url);
  368. if ( !$url)
  369. {
  370. return false;
  371. }
  372. $url = array_map('trim', $url);
  373. $url['port'] = (!isset($url['port'])) ? 80 : (int)$url['port'];
  374. $path = (isset($url['path'])) ? $url['path'] : '';
  375. if ($path == '')
  376. {
  377. $path = '/';
  378. }
  379. $path .= ( isset ( $url['query'] ) ) ? "?$url[query]" : '';
  380. if ( isset ( $url['host'] ) AND $url['host'] != gethostbyname ( $url['host'] ) )
  381. {
  382. if ( PHP_VERSION >= 5 )
  383. {
  384. $headers = get_headers("$url[scheme]://$url[host]:$url[port]$path");
  385. }
  386. else
  387. {
  388. $fp = fsockopen($url['host'], $url['port'], $errno, $errstr, 30);
  389. if (!$fp)
  390. {
  391. return false;
  392. }
  393. fputs($fp, "HEAD $path HTTP/1.1\r\nHost: $url[host]\r\n\r\n");
  394. $headers = fread ( $fp, 128 );
  395. fclose ( $fp );
  396. }
  397. $headers = ( is_array ( $headers ) ) ? implode ( "\n", $headers ) : $headers;
  398. return ( bool ) preg_match ( '#^HTTP/.*\s+[(200|301|302)]+\s#i', $headers );
  399. }
  400. return false;
  401. }
  402. }
  403. // ##################################################################################
  404. //
  405. // ErrorHandler Manager Class
  406. //
  407. // ##################################################################################
  408. class ErrorHandler extends Exception
  409. {
  410. protected $severity;
  411. public function __construct($message, $code, $severity, $filename, $lineno)
  412. {
  413. $this->message = $message;
  414. $this->code = $code;
  415. $this->severity = $severity;
  416. $this->file = $filename;
  417. $this->line = $lineno;
  418. }
  419. public function getSeverity()
  420. {
  421. return $this->severity;
  422. }
  423. function exception_error_handler($errno, $errstr, $errfile, $errline )
  424. {
  425. throw new ErrorHandler($errstr, 0, $errno, $errfile, $errline);
  426. }
  427. }
  428. ?>