PageRenderTime 69ms CodeModel.GetById 34ms RepoModel.GetById 0ms app.codeStats 1ms

/lib/functions/common.php

https://bitbucket.org/pfernandez/testlink1.9.6
PHP | 896 lines | 449 code | 88 blank | 359 comment | 94 complexity | b15a697183fcb09fac694e98978eff02 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. * This script is distributed under the GNU General Public License 2 or later.
  5. *
  6. * Load core functions for TestLink GUI
  7. * Common functions: database connection, session and data initialization,
  8. * maintain $_SESSION data, redirect page, log, etc.
  9. *
  10. * Note: this file must uses only globally used functionality and cannot include
  11. * a feature specific code because of performance and readability reasons
  12. *
  13. * @package TestLink
  14. * @author Martin Havlat, Chad Rosen
  15. * @copyright 2005, TestLink community
  16. * @version CVS: $Id: common.php,v 1.195 2010/08/31 20:08:07 franciscom Exp $
  17. * @link http://www.teamst.org/index.php
  18. * @since TestLink 1.5
  19. *
  20. * @internal Revisions:
  21. * 20100714 - asimon - BUGID 3601: show req spec link only when req mgmt is enabled
  22. * 20100616 - eloff - config_get: log warning when requested option does not exist
  23. * 20100310 - franciscom - changes to make code compatible with smarty 3
  24. * 20100207 - havlatm - cleanup
  25. * 20100124 - eloff - added $redirect parameter to checkSessionValid()
  26. * 20100124 - eloff - BUGID 3012 - added buildExternalIdString()
  27. * 20091215 - eloff - save active testplan_id to cookie
  28. * 20091121 - franciscom - getItemTemplateContents() - contribution refactored
  29. * 20090425 - amitkhullar - BUGID 2431 - Improper Session Handler
  30. * 20090409 - amitkhullar- BUGID 2354
  31. * 20090111 - franciscom - commented some required_once and some global coupling
  32. * 20081027 - havlatm - refactorization, description
  33. * removed unused $g_cache_config and some functions
  34. * 20080907 - franciscom - isValidISODateTime()
  35. * 20080518 - franciscom - translate_tc_status()
  36. * 20080412 - franciscom - templateConfiguration()
  37. * 20080326 - franciscom - config_get() - refactored removed eval()
  38. * 20071027 - franciscom - added ini_get_bool() from mantis code, needed to user
  39. * string_api.php, also from Mantis.
  40. * 20071002 - jbarchibald - BUGID 1051
  41. * 20070705 - franciscom - init_labels()
  42. * 20070623 - franciscom - improved info in header of localize_dateOrTimeStamp()
  43. */
  44. /** core and parenthal classes */
  45. require_once('object.class.php');
  46. require_once('metastring.class.php');
  47. /** library for localization */
  48. require_once('lang_api.php');
  49. /** logging functions */
  50. require_once('logging.inc.php');
  51. require_once('logger.class.php');
  52. require_once('pagestatistics.class.php');
  53. /** library of database wrapper */
  54. require_once('database.class.php');
  55. /** user right checking */
  56. require_once('roles.inc.php');
  57. /** Testlink Smarty class wrapper sets up the default smarty settings for testlink */
  58. require_once('tlsmarty.inc.php');
  59. // Needed to avoid problems with Smarty 3
  60. spl_autoload_register('tlAutoload');
  61. /** Input data validation */
  62. require_once("inputparameter.inc.php");
  63. /** @TODO use the next include only if it is used -> must be removed */
  64. require_once("testproject.class.php");
  65. require_once("treeMenu.inc.php");
  66. require_once("exec_cfield_mgr.class.php");
  67. /**
  68. * Automatic loader for PHP classes
  69. * See PHP Manual for details
  70. */
  71. // function __autoload($class_name)
  72. function tlAutoload($class_name) {
  73. // exceptions
  74. $tlClasses = null;
  75. $tlClassPrefixLen = 2;
  76. $classFileName = $class_name;
  77. if (isset($tlClasses[$classFileName])) {
  78. $len = tlStringLen($classFileName) - $tlClassPrefixLen;
  79. $classFileName = strtolower(tlSubstr($classFileName, $tlClassPrefixLen, $len));
  80. }
  81. // pf bug si require au chargement de BTSQLManager
  82. include_once $classFileName . '.class.php';
  83. }
  84. // ----- End of loading and begin functions ---------------------------------------------
  85. /** @var integer global main DB connection identifier */
  86. $db = 0;
  87. /**
  88. * TestLink connects to the database
  89. *
  90. * @return array
  91. * aa['status'] = 1 -> OK , 0 -> KO
  92. * aa['dbms_msg''] = 'ok', or $db->error_msg().
  93. */
  94. function doDBConnect(&$db) {
  95. global $g_tlLogger;
  96. $charSet = config_get('charset');
  97. $result = array('status' => 1, 'dbms_msg' => 'ok');
  98. $db = new database(DB_TYPE);
  99. $result = $db->connect(DSN, DB_HOST, DB_USER, DB_PASS, DB_NAME);
  100. if (!$result['status']) {
  101. echo $result['dbms_msg'];
  102. $result['status'] = 0;
  103. tLog('Connect to database fails!!! ' . $result['dbms_msg'], 'ERROR');
  104. } else {
  105. if ((DB_TYPE == 'mysql') && ($charSet == 'UTF-8')) {
  106. $db->exec_query("SET CHARACTER SET utf8");
  107. $db->exec_query("SET collation_connection = 'utf8_general_ci'");
  108. }
  109. }
  110. // if we establish a DB connection, we reopen the session,
  111. // to attach the db connection
  112. $g_tlLogger->endTransaction();
  113. $g_tlLogger->startTransaction();
  114. return $result;
  115. }
  116. /**
  117. * Set session data related to the current test plan
  118. * and saves a cookie with current testplan id
  119. *
  120. * @param array $tplan_info result of DB query
  121. */
  122. function setSessionTestPlan($tplan_info) {
  123. if ($tplan_info) {
  124. $_SESSION['testplanID'] = $tplan_info['id'];
  125. $_SESSION['testplanName'] = $tplan_info['name'];
  126. // Save testplan id for next session
  127. setcookie('TL_lastTestPlanForUserID_' . 1, $tplan_info['id'], TL_COOKIE_KEEPTIME, '/');
  128. tLog("Test Plan was adjusted to '" . $tplan_info['name'] . "' ID(" . $tplan_info['id'] . ')', 'INFO');
  129. } else {
  130. unset($_SESSION['testplanID']);
  131. unset($_SESSION['testplanName']);
  132. }
  133. }
  134. /**
  135. * Set home URL path
  136. * @internal Revisions:
  137. * 200806 - havlatm - removed rpath
  138. */
  139. function setPaths() {
  140. if (!isset($_SESSION['basehref'])) {
  141. $_SESSION['basehref'] = get_home_url();
  142. }
  143. }
  144. /**
  145. * Verify if user is log in. Redirect to login page if not.
  146. *
  147. * @param integer $db DB identifier
  148. * @param boolean $redirect if true (default) redirects user to login page, otherwise returns true/false as login status
  149. * */
  150. function checkSessionValid(&$db, $redirect=true) {
  151. $isValidSession = false;
  152. if (isset($_SESSION['userID']) && $_SESSION['userID'] > 0) {
  153. /** @TODO martin:
  154. Talk with Andreas to understand:
  155. 1. advantages of this approach
  156. 2. do we need to recreate it every time ? why ?
  157. * a) store just data -not all object
  158. * b) do not read again and again the same data from DB
  159. * c) this function check JUST session validity
  160. * */
  161. $now = time();
  162. $lastActivity = $_SESSION['lastActivity'];
  163. if (($now - $lastActivity) <= (config_get("sessionInactivityTimeout") * 60)) {
  164. $_SESSION['lastActivity'] = $now;
  165. $user = new tlUser($_SESSION['userID']);
  166. $user->readFromDB($db);
  167. $_SESSION['currentUser'] = $user;
  168. $isValidSession = true;
  169. }
  170. }
  171. if (!$isValidSession && $redirect) {
  172. $ip = $_SERVER["REMOTE_ADDR"];
  173. tLog('Invalid session from ' . $ip . '. Redirected to login page.', 'INFO');
  174. $fName = "login.php";
  175. $baseDir = dirname($_SERVER['SCRIPT_FILENAME']);
  176. while (!file_exists($baseDir . DIRECTORY_SEPARATOR . $fName)) {
  177. $fName = "../" . $fName;
  178. }
  179. redirect($fName . "?note=expired", "top.location");
  180. exit();
  181. }
  182. return $isValidSession;
  183. }
  184. /**
  185. * Start session
  186. */
  187. function doSessionStart() {
  188. session_set_cookie_params(99999);
  189. if (!isset($_SESSION)) {
  190. session_start();
  191. }
  192. }
  193. /**
  194. * Initialize structure of top menu for the user and the project.
  195. *
  196. * @param integer $db DB connection identifier
  197. * @uses $_SESSION Requires initialized project, test plan and user data.
  198. * @since 1.9
  199. *
  200. * @internal Revisions
  201. * 20100714 - asimon - BUGID 3601: show req spec link only when req mgmt is enabled
  202. * 20091119 - franciscom - removed global coupling
  203. */
  204. function initTopMenu(&$db) {
  205. $_SESSION['testprojectTopMenu'] = '';
  206. $guiTopMenu = config_get('guiTopMenu');
  207. // check if Project is available
  208. if (isset($_SESSION['testprojectID']) && $_SESSION['testprojectID'] > 0) {
  209. $idx = 1;
  210. foreach ($guiTopMenu as $element) {
  211. // check if Test Plan is available
  212. // BUGID 3601: check also if req mgmt is enabled
  213. if ((!isset($element['condition'])) || ($element['condition'] == '') ||
  214. (($element['condition'] == 'TestPlanAvailable') &&
  215. isset($_SESSION['testplanID']) && $_SESSION['testplanID'] > 0) ||
  216. (($element['condition'] == 'ReqMgmtEnabled') &&
  217. isset($_SESSION['testprojectOptions']->requirementsEnabled) &&
  218. $_SESSION['testprojectOptions']->requirementsEnabled)) {
  219. // (is_null($element['right']) => no right needed => display always
  220. if (is_null($element['right']) || has_rights($db, $element['right']) == "yes") {
  221. $_SESSION['testprojectTopMenu'] .= "<a href='{$element['url']}' " .
  222. "target='{$element['target']}' accesskey='{$element['shortcut']}'" .
  223. "tabindex=''" . $idx++ . "''>" . lang_get($element['label']) . "</a> |";
  224. }
  225. }
  226. }
  227. }
  228. }
  229. /**
  230. * Update Project and Test Plan data on Project change or startup
  231. * Data are stored in $_SESSION array
  232. *
  233. * If we receive TestPlan ID in the _SESSION then do some checks and if everything OK
  234. * Update this value at Session Level, to set it available in other pieces of the application
  235. *
  236. * @param integer $db DB connection identifier
  237. * @param array $hash_user_sel input data for the page ($_REQUEST)
  238. *
  239. * @uses initMenu()
  240. * @internal Revisions:
  241. * 20091111 - havlatm - menu generation added, name changed (from upd_session_tplan_tproject)
  242. * 20090726 - franciscom - getAccessibleTestPlans() now is method on user class
  243. * */
  244. function initProject(&$db, $hash_user_sel) {
  245. $tproject = new testproject($db);
  246. $user_sel = array("tplan_id" => 0, "tproject_id" => 0);
  247. $user_sel["tproject_id"] = isset($hash_user_sel['testproject']) ? intval($hash_user_sel['testproject']) : 0;
  248. $user_sel["tplan_id"] = isset($hash_user_sel['testplan']) ? intval($hash_user_sel['testplan']) : 0;
  249. $tproject_id = isset($_SESSION['testprojectID']) ? $_SESSION['testprojectID'] : 0;
  250. // test project is Test Plan container, then we start checking the container
  251. if ($user_sel["tproject_id"] != 0) {
  252. $tproject_id = $user_sel["tproject_id"];
  253. }
  254. // We need to do checks before updating the SESSION to cover the case that not defined but exists
  255. if (!$tproject_id) {
  256. $all_tprojects = $tproject->get_all();
  257. if ($all_tprojects) {
  258. $tproject_data = $all_tprojects[0];
  259. $tproject_id = $tproject_data['id'];
  260. }
  261. }
  262. $tproject->setSessionProject($tproject_id);
  263. // set a Test Plan
  264. // Refresh test project id after call to setSessionProject
  265. $tproject_id = isset($_SESSION['testprojectID']) ? $_SESSION['testprojectID'] : 0;
  266. $tplan_id = isset($_SESSION['testplanID']) ? $_SESSION['testplanID'] : null;
  267. // Now we need to validate the TestPlan
  268. // dolezalz, havlatm: added remember the last selection by cookie
  269. $cookieName = "TL_user${_SESSION['userID']}_proj${tproject_id}_testPlanId";
  270. if ($user_sel["tplan_id"] != 0) {
  271. $tplan_id = $user_sel["tplan_id"];
  272. setcookie($cookieName, $tplan_id, time() + 60 * 60 * 24 * 90, '/');
  273. } elseif (isset($_COOKIE[$cookieName])) {
  274. $tplan_id = intval($_COOKIE[$cookieName]);
  275. }
  276. // check if the specific combination of testprojectid and testplanid is valid
  277. $tplan_data = $_SESSION['currentUser']->getAccessibleTestPlans($db, $tproject_id, $tplan_id);
  278. if (is_null($tplan_data)) {
  279. // Need to get first accessible test plan for user, if any exists.
  280. $tplan_data = $_SESSION['currentUser']->getAccessibleTestPlans($db, $tproject_id);
  281. }
  282. if (!is_null($tplan_data)) {
  283. $tplan_data = $tplan_data[0];
  284. setSessionTestPlan($tplan_data);
  285. }
  286. // initialize structure of top menu for the user and the project
  287. initTopMenu($db);
  288. }
  289. /**
  290. * General GUI page initialization procedure
  291. * - init session
  292. * - init database
  293. * - check rights
  294. * - initialize project data (if requested)
  295. *
  296. * @param integer $db DB connection identifier
  297. * @param boolean $initProject (optional) Set true if adjustment of Product or
  298. * Test Plan is required; default is FALSE
  299. * @param boolean $bDontCheckSession (optional) Set to true if no session should be
  300. * started
  301. */
  302. function testlinkInitPage(&$db, $initProject = FALSE, $bDontCheckSession = false, $userRightsCheckFunction = null) {
  303. doSessionStart();
  304. setPaths();
  305. set_dt_formats();
  306. doDBConnect($db);
  307. static $pageStatistics = null;
  308. if (!$pageStatistics && (config_get('log_level') == 'EXTENDED'))
  309. $pageStatistics = new tlPageStatistics($db);
  310. if (!$bDontCheckSession)
  311. checkSessionValid($db);
  312. if ($userRightsCheckFunction)
  313. checkUserRightsFor($db, $userRightsCheckFunction);
  314. // adjust Product and Test Plan to $_SESSION
  315. if ($initProject) {
  316. initProject($db, $_REQUEST);
  317. }
  318. // used to disable the attachment feature if there are problems with repository path
  319. /** @TODO this check should not be done anytime but on login and using */
  320. global $g_repositoryType;
  321. global $g_attachments;
  322. global $g_repositoryPath;
  323. $g_attachments->disabled_msg = "";
  324. if ($g_repositoryType == TL_REPOSITORY_TYPE_FS) {
  325. $ret = checkForRepositoryDir($g_repositoryPath);
  326. if (!$ret['status_ok']) {
  327. $g_attachments->enabled = FALSE;
  328. $g_attachments->disabled_msg = $ret['msg'];
  329. }
  330. }
  331. // pf
  332. if (BT_USE) {
  333. include_once('../../plugin/BTcommon.php');
  334. include_once('plugin/BTcommon.php');
  335. }
  336. }
  337. /**
  338. * Redirect page to another one
  339. *
  340. * @param string URL of required page
  341. * @param string Browser location - use for redirection or refresh of another frame
  342. * Default: 'location'
  343. */
  344. function redirect($path, $level = 'location') {
  345. echo "<html><head></head><body>";
  346. echo "<script type='text/javascript'>";
  347. echo "$level.href='$path';";
  348. echo "</script></body></html>";
  349. exit;
  350. }
  351. /**
  352. * Security parser for input strings
  353. *
  354. * @param string $parameter
  355. * @return string cleaned parameter
  356. */
  357. function strings_stripSlashes($parameter, $bGPC = true) {
  358. if ($bGPC && !ini_get('magic_quotes_gpc'))
  359. return $parameter;
  360. if (is_array($parameter)) {
  361. $retParameter = null;
  362. if (sizeof($parameter)) {
  363. foreach ($parameter as $key => $value) {
  364. if (is_array($value))
  365. $retParameter[$key] = strings_stripSlashes($value, $bGPC);
  366. else
  367. $retParameter[$key] = stripslashes($value);
  368. }
  369. }
  370. return $retParameter;
  371. }
  372. else
  373. return stripslashes($parameter);
  374. }
  375. function to_boolean($alt_boolean) {
  376. $the_val = 1;
  377. if (is_numeric($alt_boolean) && !intval($alt_boolean)) {
  378. $the_val = 0;
  379. } else {
  380. $a_bool = array("on" => 1, "y" => 1, "off" => 0, "n" => 0);
  381. $alt_boolean = strtolower($alt_boolean);
  382. if (isset($a_bool[$alt_boolean])) {
  383. $the_val = $a_bool[$alt_boolean];
  384. }
  385. }
  386. return $the_val;
  387. }
  388. /**
  389. * Validate string by relular expression
  390. *
  391. * @param string $str2check
  392. * @param string $regexp_forbidden_chars Regular expression (perl format)
  393. *
  394. * @return boolean 1: check ok, 0:check KO
  395. *
  396. * @todo havlatm: remove as obsolete or move to inputparam.inc.php
  397. */
  398. function check_string($str2check, $regexp_forbidden_chars) {
  399. $status_ok = 1;
  400. if ($regexp_forbidden_chars != '' && !is_null($regexp_forbidden_chars)) {
  401. if (preg_match($regexp_forbidden_chars, $str2check)) {
  402. $status_ok = 0;
  403. }
  404. }
  405. return $status_ok;
  406. }
  407. function set_dt_formats() {
  408. global $g_date_format;
  409. global $g_timestamp_format;
  410. global $g_locales_date_format;
  411. global $g_locales_timestamp_format;
  412. if (isset($_SESSION['locale'])) {
  413. if ($g_locales_date_format[$_SESSION['locale']]) {
  414. $g_date_format = $g_locales_date_format[$_SESSION['locale']];
  415. }
  416. if ($g_locales_timestamp_format[$_SESSION['locale']]) {
  417. $g_timestamp_format = $g_locales_timestamp_format[$_SESSION['locale']];
  418. }
  419. }
  420. }
  421. /**
  422. * Load global configuration to function
  423. *
  424. * @param string $config_id key for identification of configuration parameter
  425. * @return mixed the configuration parameter(s)
  426. *
  427. * @internal Revisions
  428. */
  429. function config_get($config_id) {
  430. $t_value = '';
  431. $t_found = false;
  432. $logInfo = array('msg' => "config option not available: {$config_id}", 'level' => 'WARNING');
  433. if (!$t_found) {
  434. $my = "g_" . $config_id;
  435. if (($t_found = isset($GLOBALS[$my]))) {
  436. $t_value = $GLOBALS[$my];
  437. } else {
  438. $cfg = $GLOBALS['tlCfg'];
  439. if (($t_found = property_exists($cfg, $config_id))) {
  440. $t_value = $cfg->$config_id;
  441. }
  442. }
  443. if ($t_found) {
  444. $logInfo = array('msg' => "config option: {$config_id} is {$t_value}", 'level' => 'INFO');
  445. }
  446. }
  447. tLog($logInfo['msg'], $logInfo['level']);
  448. return $t_value;
  449. }
  450. /**
  451. * @return boolean Return true if the parameter is an empty string or a string
  452. * containing only whitespace, false otherwise
  453. * @author Copyright (C) 2000 - 2004 Mantis Team, Kenzaburo Ito
  454. */
  455. function is_blank($p_var) {
  456. $p_var = trim($p_var);
  457. $str_len = strlen($p_var);
  458. if (0 == $str_len) {
  459. return true;
  460. }
  461. return false;
  462. }
  463. /**
  464. * Builds the header needed to make the content available for downloading
  465. *
  466. * @param string $content the content which should be downloaded
  467. * @param string $fileName the filename
  468. * */
  469. function downloadContentsToFile($content, $fileName) {
  470. $charSet = config_get('charset');
  471. ob_get_clean();
  472. header('Pragma: public');
  473. header('Content-Type: text/plain; charset=' . $charSet . '; name=' . $fileName);
  474. header('Content-Transfer-Encoding: BASE64;');
  475. header('Content-Disposition: attachment; filename="' . $fileName . '"');
  476. echo $content;
  477. }
  478. /**
  479. * helper function for performance timing
  480. *
  481. * @TODO havlatm: Andreas, move to logger?
  482. * returns: ?
  483. */
  484. function microtime_float() {
  485. list($usec, $sec) = explode(" ", microtime());
  486. return ((float) $usec + (float) $sec);
  487. }
  488. /**
  489. * Converts a priority weight (urgency * importance) to HIGH, MEDUIM or LOW
  490. *
  491. * @return integer HIGH, MEDUIM or LOW
  492. */
  493. function priority_to_level($priority) {
  494. $levels = config_get('priority_levels');
  495. if ($priority >= $levels[HIGH])
  496. return HIGH;
  497. else if ($priority >= $levels[MEDIUM])
  498. return MEDIUM;
  499. else
  500. return LOW;
  501. }
  502. /**
  503. * Get the named php ini variable but return it as a bool
  504. *
  505. * @author Copyright (C) 2000 - 2004 Mantis Team, Kenzaburo Ito
  506. */
  507. function ini_get_bool($p_name) {
  508. $result = ini_get($p_name);
  509. if (is_string($result)) {
  510. switch ($result) {
  511. case 'off':
  512. case 'false':
  513. case 'no':
  514. case 'none':
  515. case '':
  516. case '0':
  517. return false;
  518. break;
  519. case 'on':
  520. case 'true':
  521. case 'yes':
  522. case '1':
  523. return true;
  524. break;
  525. }
  526. } else {
  527. return (bool) $result;
  528. }
  529. }
  530. /** @TODO martin: this is specific library and cannot be loaded via common.php
  531. * USE EXTRA LIBRARY
  532. // Contributed code - manish
  533. $phpxmlrpc = TL_ABS_PATH . 'third_party'. DIRECTORY_SEPARATOR . 'phpxmlrpc' .
  534. DIRECTORY_SEPARATOR . 'lib' . DIRECTORY_SEPARATOR;
  535. require_once($phpxmlrpc . 'xmlrpc.inc');
  536. require_once($phpxmlrpc . 'xmlrpcs.inc');
  537. require_once($phpxmlrpc . 'xmlrpc_wrappers.inc');
  538. */
  539. /**
  540. * Initiate the execution of a testcase through XML Server RPCs.
  541. * All the object instantiations are done here.
  542. * XML-RPC Server Settings need to be configured using the custom fields feature.
  543. * Three fields each for testcase level and testsuite level are required.
  544. * The fields are: server_host, server_port and server_path.
  545. * Precede 'tc_' for custom fields assigned to testcase level.
  546. *
  547. * @param $testcase_id: The testcase id of the testcase to be executed
  548. * @param $tree_manager: The tree manager object to read node values and testcase and parent ids.
  549. * @param $cfield_manager: Custom Field manager object, to read the XML-RPC server params.
  550. * @return map:
  551. * keys: 'result','notes','message'
  552. * values: 'result' -> (Pass, Fail or Blocked)
  553. * 'notes' -> Notes text
  554. * 'message' -> Message from server
  555. */
  556. /*
  557. function executeTestCase($testcase_id,$tree_manager,$cfield_manager){
  558. //Fetching required params from the entire node hierarchy
  559. $server_params = $cfield_manager->getXMLServerParams($testcase_id);
  560. $ret=array('result'=>AUTOMATION_RESULT_KO,
  561. 'notes'=>AUTOMATION_NOTES_KO, 'message'=>'');
  562. $server_host = "";
  563. $server_port = "";
  564. $server_path = "";
  565. $do_it=false;
  566. if( ($server_params != null) or $server_params != ""){
  567. $server_host = $server_params["xml_server_host"];
  568. $server_port = $server_params["xml_server_port"];
  569. $server_path = $server_params["xml_server_path"];
  570. $do_it=true;
  571. }
  572. if($do_it)
  573. {
  574. // Make an object to represent our server.
  575. // If server config objects are null, it returns an array with appropriate values
  576. // (-1 for executions results, and fault code and error message for message.
  577. $xmlrpc_client = new xmlrpc_client($server_path,$server_host,$server_port);
  578. $tc_info = $tree_manager->get_node_hierarchy_info($testcase_id);
  579. $testcase_name = $tc_info['name'];
  580. //Create XML-RPC Objects to pass on to the the servers
  581. $myVar1 = new xmlrpcval($testcase_name,'string');
  582. $myvar2 = new xmlrpcval($testcase_id,'string');
  583. $messageToServer = new xmlrpcmsg('ExecuteTest', array($myVar1,$myvar2));
  584. $serverResp = $xmlrpc_client->send($messageToServer);
  585. $myResult=AUTOMATION_RESULT_KO;
  586. $myNotes=AUTOMATION_NOTES_KO;
  587. if(!$serverResp) {
  588. $message = lang_get('test_automation_server_conn_failure');
  589. } elseif ($serverResp->faultCode()) {
  590. $message = lang_get("XMLRPC_error_number") . $serverResp->faultCode() . ": ".$serverResp->faultString();
  591. }
  592. else {
  593. $message = lang_get('test_automation_exec_ok');
  594. $arrayVal = $serverResp->value();
  595. $myResult = $arrayVal->arraymem(0)->scalarval();
  596. $myNotes = $arrayVal->arraymem(1)->scalarval();
  597. }
  598. $ret = array('result'=>$myResult, 'notes'=>$myNotes, 'message'=>$message);
  599. } //$do_it
  600. return $ret;
  601. } // function end
  602. */
  603. /**
  604. * Trim string and limit to N chars
  605. *
  606. * @param string
  607. * @param int [len]: how many chars return
  608. *
  609. * @return string trimmed string
  610. *
  611. * @author Francisco Mancardi - 20050905 - refactoring
  612. */
  613. function trim_and_limit($s, $len = 100) {
  614. $s = trim($s);
  615. if (tlStringLen($s) > $len) {
  616. $s = tlSubStr($s, 0, $len);
  617. }
  618. return $s;
  619. }
  620. /** @todo havlatm - 20100207 - what's that? and why here. Remove' */
  621. // nodes_order format: NODE_ID-?,NODE_ID-?
  622. // 2-0,10-0,3-0
  623. function transform_nodes_order($nodes_order, $node_to_exclude=null) {
  624. $fa = explode(',', $nodes_order);
  625. foreach ($fa as $key => $value) {
  626. // $value= X-Y
  627. $fb = explode('-', $value);
  628. if (is_null($node_to_exclude) || $fb[0] != $node_to_exclude) {
  629. $nodes_id[] = $fb[0];
  630. }
  631. }
  632. return $nodes_id;
  633. }
  634. /**
  635. * Checks $_FILES for errors while uploading
  636. *
  637. * @param array $fInfo an array used by uploading files ($_FILES)
  638. * @return string containing an error message (if any)
  639. */
  640. function getFileUploadErrorMessage($fInfo) {
  641. $msg = null;
  642. if (isset($fInfo['error'])) {
  643. switch ($fInfo['error']) {
  644. case UPLOAD_ERR_INI_SIZE:
  645. $msg = lang_get('error_file_size_larger_than_maximum_size_check_php_ini');
  646. break;
  647. case UPLOAD_ERR_FORM_SIZE:
  648. $msg = lang_get('error_file_size_larger_than_maximum_size');
  649. break;
  650. case UPLOAD_ERR_PARTIAL:
  651. case UPLOAD_ERR_NO_FILE:
  652. $msg = lang_get('error_file_upload');
  653. break;
  654. }
  655. }
  656. return $msg;
  657. }
  658. /**
  659. * Redirect to a page with static html defined in locale/en_GB/texts.php
  660. *
  661. * @param string $key keyword for finding exact html text in definition array
  662. */
  663. function show_instructions($key, $refreshTree=0) {
  664. $myURL = $_SESSION['basehref'] . "lib/general/staticPage.php?key={$key}";
  665. if ($refreshTree) {
  666. $myURL .= "&refreshTree=1";
  667. }
  668. redirect($myURL);
  669. }
  670. /**
  671. * @TODO: franciscom - 20091003 - document return value
  672. */
  673. function templateConfiguration($template2get=null) {
  674. $custom_templates = config_get('tpl');
  675. $access_key = $template2get;
  676. if (is_null($access_key)) {
  677. $access_key = str_replace('.php', '', basename($_SERVER['SCRIPT_NAME']));
  678. }
  679. $path_parts = explode("/", dirname($_SERVER['SCRIPT_NAME']));
  680. $last_part = array_pop($path_parts);
  681. $tcfg = new stdClass();
  682. $tcfg->template_dir = "{$last_part}/";
  683. $tcfg->default_template = isset($custom_templates[$access_key]) ? $custom_templates[$access_key] : ($access_key . '.tpl');
  684. $tcfg->template = null;
  685. return $tcfg;
  686. }
  687. /**
  688. * Check if an string is a valid ISO date/time
  689. * accepted format: YYYY-MM-DD HH:MM:SS
  690. *
  691. * @param string $ISODateTime datetime to check
  692. * @return boolean True if string has correct format
  693. *
  694. * @internal
  695. * rev: 20080907 - franciscom - Code taked form PHP manual
  696. */
  697. function isValidISODateTime($ISODateTime) {
  698. $dateParts = array('YEAR' => 1, 'MONTH' => 2, 'DAY' => 3);
  699. $matches = null;
  700. $status_ok = false;
  701. if (preg_match("/^(\d{4})-(\d{2})-(\d{2}) ([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$/", $ISODateTime, $matches)) {
  702. $status_ok = checkdate($matches[$dateParts['MONTH']], $matches[$dateParts['DAY']], $matches[$dateParts['YEAR']]);
  703. }
  704. return $status_ok;
  705. }
  706. function checkUserRightsFor(&$db, $pfn) {
  707. $script = basename($_SERVER['PHP_SELF']);
  708. $currentUser = $_SESSION['currentUser'];
  709. $bExit = false;
  710. $action = null;
  711. if (!$pfn($db, $currentUser, $action)) {
  712. if (!$action)
  713. $action = "any";
  714. logAuditEvent(TLS("audit_security_user_right_missing", $currentUser->login, $script, $action), $action, $currentUser->dbID, "users");
  715. $bExit = true;
  716. }
  717. if ($bExit) {
  718. $myURL = $_SESSION['basehref'];
  719. redirect($myURL, "top.location");
  720. exit();
  721. }
  722. }
  723. function tlStringLen($str) {
  724. $charset = config_get('charset');
  725. $nLen = iconv_strlen($str, $charset);
  726. if ($nLen === false) {
  727. throw new Exception("Invalid UTF-8 Data detected!");
  728. }
  729. return $nLen;
  730. }
  731. function tlSubStr($str, $start, $length = null) {
  732. $charset = config_get('charset');
  733. if ($length === null) {
  734. $length = iconv_strlen($str, $charset);
  735. }
  736. return iconv_substr($str, $start, $length, $charset);
  737. }
  738. /**
  739. * Get text from a configured item template for editor objects
  740. *
  741. * @param $itemTemplate identifies a TestLink item that can have
  742. * templates that can be loaded when creating an item to semplify
  743. * or guide user's work.
  744. * $itemTemplate is a property (of type stdClass) of $tlCfg configuration object.
  745. *
  746. * supported values:
  747. * testcase_template
  748. *
  749. * @param $webEditorName webeditor name, that identifies a propety of $tlCfg->$itemTemplate
  750. * that holds input tenmplate configuration
  751. *
  752. * @param $defaultText text to use if:
  753. * $tlCfg->itemTemplate OR $tlCfg->itemTemplate->$webEditorName
  754. * does not exists.
  755. *
  756. */
  757. function getItemTemplateContents($itemTemplate, $webEditorName, $defaultText='') {
  758. $editorTemplate = config_get($itemTemplate);
  759. $value = $defaultText;
  760. if (!is_null($editorTemplate)) {
  761. if (property_exists($editorTemplate, $webEditorName)) {
  762. switch ($editorTemplate->$webEditorName->type) {
  763. case 'string':
  764. $value = $editorTemplate->$webEditorName->value;
  765. break;
  766. case 'string_id':
  767. $value = lang_get($editorTemplate->$webEditorName->value);
  768. break;
  769. case 'file':
  770. $value = getFileContents($editorTemplate->$webEditorName->value);
  771. if (is_null($value)) {
  772. $value = lang_get('problems_trying_to_access_template') .
  773. " {$editorTemplate->$webEditorName->value} ";
  774. }
  775. break;
  776. default:
  777. $value = '';
  778. break;
  779. }
  780. }
  781. }
  782. return $value;
  783. }
  784. /**
  785. * Builds a string $testCasePrefix . $glueChar . $external_id
  786. *
  787. * @param string $testCasePrefix prefix for the project without glue character
  788. * @param mixed $external_id
  789. */
  790. function buildExternalIdString($testCasePrefix, $external_id) {
  791. static $glueChar;
  792. if (!$glueChar) {
  793. $glueChar = config_get('testcase_cfg')->glue_character;
  794. }
  795. return $testCasePrefix . $glueChar . $external_id;
  796. }
  797. ?>