PageRenderTime 84ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 1ms

/includes/cleanup_functions.php

https://github.com/web2project/web2project
PHP | 5315 lines | 3857 code | 612 blank | 846 comment | 730 complexity | 895caaf8be2a1fcf8079a875b53e6251 MD5 | raw file
Possible License(s): LGPL-2.1
  1. <?php
  2. /**
  3. * This file exists in order to list individual functions which need to be
  4. * cleaned up, reorganized or eliminated based on usage. Before you touch
  5. * these, please ensure there are Unit Tests to validate that things work
  6. * before and after.
  7. * @todo/TODO: Every single function in this file.
  8. *
  9. * WARNING: The functions in this file are likely to move to other files as they
  10. * are updated. Since this file is included within main_functions.php
  11. * this shouldn't be a problem.
  12. */
  13. function is_task_in_gantt_arr($task)
  14. {
  15. global $gantt_arr;
  16. $n = count($gantt_arr);
  17. for ($x = 0; $x < $n; $x++) {
  18. if ($gantt_arr[$x][0]['task_id'] == $task['task_id']) {
  19. return true;
  20. }
  21. }
  22. return false;
  23. }
  24. function notifyHR($address, $notUsed, $uaddress, $uusername, $logname, $notUsed2, $userid)
  25. {
  26. global $AppUI;
  27. $emailManager = new w2p_Output_EmailManager($AppUI);
  28. $body = $emailManager->notifyHR($uusername, $logname, $uaddress, $userid);
  29. $mail = new w2p_Utilities_Mail();
  30. $mail->To($address);
  31. $mail->Subject('New External User Created');
  32. $mail->Body($body);
  33. return $mail->Send();
  34. }
  35. function notifyNewUserCredentials($address, $username, $logname, $logpwd)
  36. {
  37. global $AppUI;
  38. $emailManager = new w2p_Output_EmailManager($AppUI);
  39. $body = $emailManager->notifyNewUserCredentials($username, $logname, $logpwd);
  40. $mail = new w2p_Utilities_Mail();
  41. $mail->To($address);
  42. $mail->Subject('New Account Created - web2Project Project Management System');
  43. $mail->Body($body);
  44. return $mail->Send();
  45. }
  46. function clean_value($str)
  47. {
  48. $bad_values = array("'");
  49. return str_replace($bad_values, '', $str);
  50. }
  51. function strUTF8Decode($text)
  52. {
  53. if (extension_loaded('mbstring')) {
  54. $encoding = mb_detect_encoding($text.' ');
  55. }
  56. if (function_exists('iconv')) {
  57. $text = mb_convert_encoding($text, 'UTF-8', $encoding);
  58. //iconv($encoding, 'UTF-8', $text);
  59. } elseif (function_exists('utf8_decode')) {
  60. $text = utf8_decode($text);
  61. }
  62. // mb functions don't seam to work well here for some reason as the output gets corrupted.
  63. // iconv is doing the job just fine though
  64. return $text;
  65. }
  66. /**
  67. * utility functions for the preparation of task data for GANTT PDF
  68. *
  69. * @todo some of these functions are not needed, need to trim this down
  70. *
  71. */
  72. // PYS : utf_8 decoding as suggested in Vbulletin #3987
  73. function strEzPdf($text)
  74. {
  75. if (function_exists('iconv') && function_exists('mb_detect_encoding')) {
  76. $text = iconv(mb_detect_encoding($text." "), 'UTF-8', $text);
  77. }
  78. return $text;
  79. }
  80. function dumb_slice( $gantt_arr, $length = 25 )
  81. {
  82. $sliced_array = array();
  83. $pages = (int) count($gantt_arr) / $length;
  84. for ( $i = 0; $i <= $pages; $i++ ) {
  85. $sliced_array[] = array_slice($gantt_arr, $i * $length, $length);
  86. }
  87. return $sliced_array;
  88. }
  89. /**
  90. *
  91. * END OF GANTT PDF UTILITY FUNCTIONS
  92. *
  93. */
  94. /**
  95. * This is a kludgy mess because of how the arraySelectTree function is used..
  96. * it expects - nay, demands! - that the first element of the subarray is the
  97. * id and the third is the parent id. In most cases, that is fine.. in this
  98. * one we're using the existing ACL-respecting functions and it has additional
  99. * fields in "improper" places.
  100. */
  101. function temp_filterArrayForSelectTree($projectData)
  102. {
  103. unset($projectData['project_id']);
  104. unset($projectData['project_color_identifier']);
  105. unset($projectData['project_name']);
  106. unset($projectData['project_start_date']);
  107. unset($projectData['project_end_date']);
  108. unset($projectData['project_company']);
  109. unset($projectData['project_parent']);
  110. unset($projectData[1]);
  111. unset($projectData[3]);
  112. unset($projectData[4]);
  113. unset($projectData[5]);
  114. $projectData[6] = ($projectData[0] == $projectData[6]) ? '' : $projectData[6];
  115. return array_values($projectData);
  116. }
  117. function getReadableModule()
  118. {
  119. $q = new w2p_Database_Query;
  120. $q->addTable('modules');
  121. $q->addQuery('mod_directory');
  122. $q->addWhere('mod_active = 1');
  123. $q->addOrder('mod_ui_order');
  124. $modules = $q->loadColumn();
  125. foreach ($modules as $mod) {
  126. if (canAccess($mod)) {
  127. return $mod;
  128. }
  129. }
  130. return null;
  131. }
  132. /**
  133. * This function is used to check permissions.
  134. */
  135. function checkFlag($flag, $perm_type, $old_flag)
  136. {
  137. if ($old_flag) {
  138. return (($flag == PERM_DENY) || // permission denied
  139. ($perm_type == PERM_EDIT && $flag == PERM_READ) // we ask for editing, but are only allowed to read
  140. ) ? 0 : 1;
  141. } else {
  142. if ($perm_type == PERM_READ) {
  143. return ($flag != PERM_DENY) ? 1 : 0;
  144. } else {
  145. // => $perm_type == PERM_EDIT
  146. return ($flag == $perm_type) ? 1 : 0;
  147. }
  148. }
  149. }
  150. /**
  151. * This function checks certain permissions for
  152. * a given module and optionally an item_id.
  153. *
  154. * $perm_type can be PERM_READ or PERM_EDIT
  155. */
  156. function isAllowed($perm_type, $mod, $item_id = 0)
  157. {
  158. $invert = false;
  159. switch ($perm_type) {
  160. case PERM_READ:
  161. $perm_type = 'view';
  162. break;
  163. case PERM_EDIT:
  164. $perm_type = 'edit';
  165. break;
  166. case PERM_ALL:
  167. $perm_type = 'edit';
  168. break;
  169. case PERM_DENY:
  170. $perm_type = 'view';
  171. $invert = true;
  172. break;
  173. }
  174. $allowed = getPermission($mod, $perm_type, $item_id);
  175. if ($invert) {
  176. return !$allowed;
  177. }
  178. return $allowed;
  179. }
  180. function getPermission($mod, $perm, $item_id = 0)
  181. {
  182. // First check if the module is readable, i.e. has view permission.
  183. $perms = &$GLOBALS['AppUI']->acl();
  184. $result = $perms->checkModule($mod, $perm);
  185. // If we have access then we need to ensure we are not denied access to the particular
  186. // item.
  187. if ($result && $item_id) {
  188. if ($perms->checkModuleItemDenied($mod, $perm, $item_id)) {
  189. $result = false;
  190. }
  191. }
  192. // If denied we need to check if we are allowed the task. This can be done
  193. // a lot better in PHPGACL, but is here for compatibility.
  194. if ($mod == 'tasks' && !$result && $item_id > 0) {
  195. $q = new w2p_Database_Query;
  196. $q->addTable('tasks');
  197. $q->addQuery('task_project');
  198. $q->addWhere('task_id = ' . (int) $item_id);
  199. $project_id = $q->loadResult();
  200. $result = getPermission('projects', $perm, $project_id);
  201. }
  202. return $result;
  203. }
  204. function canView($mod, $item_id = 0)
  205. {
  206. return getPermission($mod, 'view', $item_id);
  207. }
  208. function canEdit($mod, $item_id = 0)
  209. {
  210. return getPermission($mod, 'edit', $item_id);
  211. }
  212. function canAdd($mod, $item_id = 0)
  213. {
  214. return getPermission($mod, 'add', $item_id);
  215. }
  216. function canDelete($mod, $item_id = 0)
  217. {
  218. return getPermission($mod, 'delete', $item_id);
  219. }
  220. function canAccess($mod)
  221. {
  222. return getPermission($mod, 'access');
  223. }
  224. function buildTaskTree($task_data, $depth = 0, $projTasks, $all_tasks, $parents, $task_parent, $task_id)
  225. {
  226. $output = '';
  227. $projTasks[$task_data['task_id']] = $task_data['task_name'];
  228. $task_data['task_name'] = mb_strlen($task_data['task_name']) > 45 ? mb_substr($task_data['task_name'], 0, 45) . '...' : $task_data['task_name'];
  229. $selected = $task_data['task_id'] == $task_parent ? ' selected="selected"' : '';
  230. $output .= '<option value="' . $task_data['task_id'] . '"' . $selected . '>' . str_repeat('&nbsp;', $depth * 3) . w2PFormSafe($task_data['task_name']) . '</option>';
  231. if (isset($parents[$task_data['task_id']])) {
  232. foreach ($parents[$task_data['task_id']] as $child_task) {
  233. if ($child_task != $task_id) {
  234. $output .= buildTaskTree($all_tasks[$child_task], ($depth + 1), $projTasks, $all_tasks, $parents, $task_parent, $task_id);
  235. }
  236. }
  237. }
  238. return $output;
  239. }
  240. // from modules/tasks/addedit.php and modules/projectdesigners/vw_actions.php
  241. function build_date_list(&$date_array, $row)
  242. {
  243. global $project;
  244. // if this task_dynamic is not tracked, set end date to proj start date
  245. if (!in_array($row['task_dynamic'], CTask::$tracked_dynamics)) {
  246. $date = new w2p_Utilities_Date($project->project_start_date);
  247. } elseif ($row['task_milestone'] == 0) {
  248. $date = new w2p_Utilities_Date($row['task_end_date']);
  249. } else {
  250. $date = new w2p_Utilities_Date($row['task_start_date']);
  251. }
  252. $sdate = $date->format('%d/%m/%Y');
  253. $shour = $date->format('%H');
  254. $smin = $date->format('%M');
  255. $date_array[$row['task_id']] = array($row['task_name'], $sdate, $shour, $smin);
  256. }
  257. // from modules/tasks/ae_dates.php
  258. function cal_work_day_conv($val)
  259. {
  260. global $locale_char_set, $AppUI;
  261. setlocale(LC_TIME, 'en');
  262. $wk = Date_Calc::getCalendarWeek(null, null, null, '%a', LOCALE_FIRST_DAY);
  263. setlocale(LC_ALL, $AppUI->user_lang);
  264. $day_name = $AppUI->_($wk[($val - LOCALE_FIRST_DAY) % 7]);
  265. $day_name = utf8_encode($day_name);
  266. return htmlspecialchars($day_name, ENT_COMPAT, $locale_char_set);
  267. }
  268. function __extract_from_showtask(&$arr, $level, $today_view, $listTable, $fields = array())
  269. {
  270. return '';
  271. }
  272. /**
  273. * @param $arr
  274. * @param $level
  275. * @param $today_view
  276. * @param $s
  277. * @param $m
  278. * @param $jsTaskId
  279. * @param $expanded
  280. * @return array
  281. */
  282. function __extract_from_showtask2($arr, $level, $today_view, $s, $m, $jsTaskId, $expanded)
  283. {
  284. $s .= '<td style="width: ' . (($today_view) ? '50%' : '90%') . '" class="data _name">';
  285. //level
  286. if ($level == -1) {
  287. $s .= '...';
  288. }
  289. for ($y = 0; $y < $level; $y++) {
  290. if ($y + 1 == $level) {
  291. $image = w2PfindImage('corner-dots.gif', $m);
  292. } else {
  293. $image = w2PfindImage('shim.gif', $m);
  294. }
  295. $s .= '<img src="' . $image . '" width="16" height="12" border="0" alt=""/>';
  296. }
  297. if ($arr['task_description'] && !$arr['task_milestone']) {
  298. $s .= w2PtoolTip('Task Description', substr($arr['task_description'], 0, 1000), true);
  299. }
  300. if (isset($arr['task_nr_of_children']) && $arr['task_nr_of_children']) {
  301. $is_parent = true;
  302. } else {
  303. $is_parent = false;
  304. }
  305. if ($arr['task_milestone'] > 0) {
  306. $s .= '&nbsp;<a href="./index.php?m=tasks&amp;a=view&amp;task_id=' . $arr['task_id'] . '" ><b>' . $arr['task_name'] . '</b></a>&nbsp;<img src="' . w2PfindImage('icons/milestone.gif') . '" />';
  307. } elseif ($arr['task_dynamic'] == '1' || $is_parent) {
  308. $open_link = '<a href="javascript: void(0);"><img onclick="expand_collapse(\'' . $jsTaskId . '\', \'tblProjects\',\'\',' . ($level++) . ');" id="' . $jsTaskId . '_collapse" src="' . w2PfindImage('icons/collapse.gif') . '" class="center" ' . (!$expanded ? 'style="display:none"' : '') . ' /><img onclick="expand_collapse(\'' . $jsTaskId . '\', \'tblProjects\',\'\',' . ($level++) . ');" id="' . $jsTaskId . '_expand" src="' . w2PfindImage('icons/expand.gif') . '" class="center" ' . ($expanded ? 'style="display:none"' : '') . ' /></a>';
  309. $s .= $open_link;
  310. if ($arr['task_dynamic'] == '1') {
  311. $s .= '&nbsp;<a href="./index.php?m=tasks&amp;a=view&amp;task_id=' . $arr['task_id'] . '" ><b><i>' . $arr['task_name'] . '</i></b></a>';
  312. } else {
  313. $s .= '&nbsp;<a href="./index.php?m=tasks&amp;a=view&amp;task_id=' . $arr['task_id'] . '" >' . $arr['task_name'] . '</a>';
  314. }
  315. } else {
  316. $s .= '&nbsp;<a href="./index.php?m=tasks&amp;a=view&amp;task_id=' . $arr['task_id'] . '" >' . $arr['task_name'] . '</a>';
  317. }
  318. if ($arr['task_description'] && !$arr['task_milestone']) {
  319. $s .= w2PendTip();
  320. }
  321. $s .= '</td>';
  322. return $s;
  323. }
  324. function showtask_new(&$arr, $level = 0, $today_view = false, $listTable = null, $fields = array())
  325. {
  326. return __extract_from_showtask($arr, $level, $today_view, $listTable, $fields);
  327. }
  328. /*
  329. * gantt_arr [ project_id ] [ 0 ] is a task "object" : task['task_id'], task['task_access'], task['task_owner'], task['task_name'], task['project_name']
  330. * task['task_start_date'], task['task_end_date'], task['task_percent_complete'], ['task_milestone']
  331. * gantt_arr [ project_id ] [ 1 ] is the level
  332. *
  333. * project_id is "optional": a 0 value means we re not handling projects
  334. *
  335. * adds a bidimensional array:
  336. * -1st level: composed of integer project_id
  337. * -2nd level: composed of an array of two items: task "object", integer level
  338. */
  339. function showgtask(&$a, $level = 0, $notUsed = 0)
  340. {
  341. /* Add tasks to gantt chart */
  342. global $gantt_arr;
  343. if (!is_task_in_gantt_arr($a)) {
  344. $gantt_arr[] = array($a, $level);
  345. }
  346. }
  347. function findchild_new(&$tarr, $parent, $level = 0)
  348. {
  349. global $shown_tasks;
  350. $level++;
  351. $n = count($tarr);
  352. for ($x = 0; $x < $n; $x++) {
  353. if ($tarr[$x]['task_parent'] == $parent && $tarr[$x]['task_parent'] != $tarr[$x]['task_id']) {
  354. echo showtask_new($tarr[$x], $level, true);
  355. $shown_tasks[$tarr[$x]['task_id']] = $tarr[$x]['task_id'];
  356. findchild_new($tarr, $tarr[$x]['task_id'], $level);
  357. }
  358. }
  359. }
  360. function findchild_gantt(&$tarr, $parent, $level = 0)
  361. {
  362. $level++;
  363. $n = count($tarr);
  364. for ($x = 0; $x < $n; $x++) {
  365. if ($tarr[$x]['task_parent'] == $parent && $tarr[$x]['task_parent'] != $tarr[$x]['task_id']) {
  366. showgtask($tarr[$x], $level, $tarr[$x]['project_id']);
  367. findchild_gantt($tarr, $tarr[$x]['task_id'], $level);
  368. }
  369. }
  370. }
  371. // from modules/tasks/tasks.class.php
  372. function array_csort() { //coded by Ichier2003
  373. $args = func_get_args();
  374. $marray = array_shift($args);
  375. if (empty($marray)) {
  376. return array();
  377. }
  378. $i = 0;
  379. $msortline = 'return(array_multisort(';
  380. $sortarr = array();
  381. foreach ($args as $arg) {
  382. $i++;
  383. if (is_string($arg)) {
  384. for ($j = 0, $j_cmp = count($marray); $j < $j_cmp; $j++) {
  385. /* we have to calculate the end_date via start_date+duration for
  386. ** end='0000-00-00 00:00:00' before sorting, see mantis #1509:
  387. ** Task definition writes the following to the DB:
  388. ** A without start date: start = end = NULL
  389. ** B with start date and empty end date: start = startdate,
  390. end = '0000-00-00 00:00:00'
  391. ** C start + end date: start= startdate, end = end date
  392. ** A the end_date for the middle task (B) is ('dynamically') calculated on display
  393. ** via start_date+duration, it may be that the order gets wrong due to the fact
  394. ** that sorting has taken place _before_.
  395. */
  396. if ($marray[$j]['task_end_date'] == '0000-00-00 00:00:00') {
  397. $marray[$j]['task_end_date'] = calcEndByStartAndDuration($marray[$j]);
  398. }
  399. if ('' == $arg) { continue; }
  400. $sortarr[$i][] = $marray[$j][$arg];
  401. }
  402. } else {
  403. $sortarr[$i] = $arg;
  404. }
  405. if (!is_array($sortarr[$i])) {
  406. continue;
  407. }
  408. $msortline .= '$sortarr[' . $i . '],';
  409. }
  410. $msortline .= '$marray));';
  411. eval($msortline);
  412. return $marray;
  413. }
  414. // from modules/tasks/tasks.class.php
  415. /*
  416. ** Calc End Date via Startdate + Duration
  417. ** @param array task A DB row from the earlier fetched tasklist
  418. ** @return string Return calculated end date in MySQL-TIMESTAMP format
  419. */
  420. function calcEndByStartAndDuration($task)
  421. {
  422. $end_date = new w2p_Utilities_Date($task['task_start_date']);
  423. $end_date->addSeconds($task['task_duration'] * $task['task_duration_type'] * 3600);
  424. return $end_date->format(FMT_DATETIME_MYSQL);
  425. }
  426. // from modules/tasks/tasks.class.php
  427. function sort_by_item_title($title, $item_name, $item_type, $a = '')
  428. {
  429. global $AppUI, $project_id, $task_id, $m;
  430. global $task_sort_item1, $task_sort_type1, $task_sort_order1;
  431. global $task_sort_item2, $task_sort_type2, $task_sort_order2;
  432. if ($task_sort_item2 == $item_name) {
  433. $item_order = $task_sort_order2;
  434. }
  435. if ($task_sort_item1 == $item_name) {
  436. $item_order = $task_sort_order1;
  437. }
  438. $s = '';
  439. if (isset($item_order)) {
  440. $show_icon = true;
  441. } else {
  442. $show_icon = false;
  443. $item_order = SORT_DESC;
  444. }
  445. /* flip the sort order for the link */
  446. $item_order = ($item_order == SORT_ASC) ? SORT_DESC : SORT_ASC;
  447. if ($m == 'tasks') {
  448. $s .= '<a href="./index.php?m=tasks' . (($task_id > 0) ? ('&amp;a=view&amp;task_id=' . $task_id) : $a);
  449. } elseif ($m == 'calendar') {
  450. $s .= '<a href="./index.php?m=events&amp;a=day_view';
  451. } else {
  452. $s .= '<a href="./index.php?m=projects&amp;bypass=1' . (($project_id > 0) ? ('&amp;a=view&amp;project_id=' . $project_id) : '');
  453. }
  454. $s .= '&amp;task_sort_item1=' . $item_name;
  455. $s .= '&amp;task_sort_type1=' . $item_type;
  456. $s .= '&amp;task_sort_order1=' . $item_order;
  457. if ($task_sort_item1 == $item_name) {
  458. $s .= '&amp;task_sort_item2=' . $task_sort_item2;
  459. $s .= '&amp;task_sort_type2=' . $task_sort_type2;
  460. $s .= '&amp;task_sort_order2=' . $task_sort_order2;
  461. } else {
  462. $s .= '&amp;task_sort_item2=' . $task_sort_item1;
  463. $s .= '&amp;task_sort_type2=' . $task_sort_type1;
  464. $s .= '&amp;task_sort_order2=' . $task_sort_order1;
  465. }
  466. $s .= '" class="hdr">' . $AppUI->_($title);
  467. if ($show_icon) {
  468. $s .= '&nbsp;<img src="' . w2PfindImage('arrow-' . (($item_order == SORT_ASC) ? 'up' : 'down') . '.gif') . '" />';
  469. }
  470. return $s.'</a>';
  471. }
  472. // from modules/tasks/tasksperuser_sub.php
  473. function doChildren($list, $N, $id, $uid, $level, $maxlevels, $display_week_hours, $ss, $se)
  474. {
  475. $tmp = '';
  476. if ($maxlevels == -1 || $level < $maxlevels) {
  477. for ($c = 0; $c < $N; $c++) {
  478. $task = $list[$c];
  479. if (($task->task_parent == $id) and isChildTask($task)) {
  480. // we have a child, do we have the user as a member?
  481. if (isMemberOfTask($list, $N, $uid, $task)) {
  482. $tmp .= displayTask($list, $task, $level, $display_week_hours, $ss, $se, $uid);
  483. $tmp .= doChildren($list, $N, $task->task_id, $uid, $level++, $maxlevels, $display_week_hours, $ss, $se);
  484. }
  485. }
  486. }
  487. }
  488. return $tmp;
  489. }
  490. // from modules/reports/tasksperuser.php
  491. function doChildren_r($list, $Lusers, $N, $id, $uid, $level, $maxlevels, $display_week_hours, $ss, $se, $log_all_projects = false)
  492. {
  493. $tmp = "";
  494. if ($maxlevels == -1 || $level < $maxlevels) {
  495. for ($c = 0; $c < $N; $c++) {
  496. $task = $list[$c];
  497. if (($task->task_parent == $id) and isChildTask($task)) {
  498. // we have a child, do we have the user as a member?
  499. if (isMemberOfTask_r($list, $Lusers, $N, $uid, $task)) {
  500. $tmp .= displayTask_r($list, $task, $level, $display_week_hours, $ss, $se, $log_all_projects, $uid);
  501. $tmp .= doChildren_r($list, $Lusers, $N, $task->task_id, $uid, $level++, $maxlevels, $display_week_hours, $ss, $se, $log_all_projects);
  502. }
  503. }
  504. }
  505. }
  506. return $tmp;
  507. }
  508. // from modules/tasks/tasksperuser_sub.php
  509. function isMemberOfTask($notUsed, $notUsed2, $user_id, $task)
  510. {
  511. global $user_assigned_tasks;
  512. if (isset($user_assigned_tasks[$user_id])) {
  513. if (in_array($task->task_id, $user_assigned_tasks[$user_id])) {
  514. return true;
  515. }
  516. }
  517. return false;
  518. }
  519. // from modules/reports/tasksperuser.php
  520. function isMemberOfTask_r($list, $Lusers, $N, $user_id, $task)
  521. {
  522. for ($i = 0; $i < $N && $list[$i]->task_id != $task->task_id; $i++)
  523. ;
  524. $users = $Lusers[$i];
  525. foreach ($users as $task_user_id => $notUsed) {
  526. if ($task_user_id == $user_id) {
  527. return true;
  528. }
  529. }
  530. // check child tasks if any
  531. for ($c = 0; $c < $N; $c++) {
  532. $ntask = $list[$c];
  533. if (($ntask->task_parent == $task->task_id) and isChildTask($ntask)) {
  534. // we have a child task
  535. if (isMemberOfTask_r($list, $Lusers, $N, $user_id, $ntask)) {
  536. return true;
  537. }
  538. }
  539. }
  540. return false;
  541. }
  542. // from modules/tasks/tasksperuser_sub.php
  543. function displayTask($list, $task, $level, $display_week_hours, $fromPeriod, $toPeriod, $user_id)
  544. {
  545. global $AppUI, $durnTypes, $active_users, $zi, $projects;
  546. //if the user has no permission to the project don't show the tasks
  547. if (!(key_exists($task->task_project, $projects))) {
  548. return;
  549. }
  550. $htmlHelper = new w2p_Output_HTMLHelper($AppUI);
  551. $zi++;
  552. $users = $task->task_assigned_users;
  553. $task->userPriority = $task->getUserSpecificTaskPriority($user_id);
  554. $project = $task->getProject();
  555. $tmp = '<tr>';
  556. $tmp .= '<td align="center" nowrap="nowrap">';
  557. $tmp .= '<input type="checkbox" name="selected_task[' . $task->task_id . ']" value="' . $task->task_id . '" />';
  558. $tmp .= '</td>';
  559. $tmp .= $htmlHelper->createCell('user_priority', $task->userPriority);
  560. $tmp .= '<td class="_name">';
  561. for ($i = 0; $i < $level; $i++) {
  562. $tmp .= '&#160';
  563. }
  564. if ($task->task_milestone == true) {
  565. $tmp .= '<b>';
  566. }
  567. if ($level >= 1) {
  568. $tmp .= '<img src="' . w2PfindImage('corner-dots.gif') . '" width="16" height="12" alt="" style="float: left;">';
  569. }
  570. $tmp .= '<a href="?m=tasks&a=view&task_id=' . $task->task_id . '">' . $task->task_name . '</a>';
  571. if ($task->task_milestone == true) {
  572. $tmp .= '</b>';
  573. }
  574. if ($task->task_priority < 0) {
  575. $tmp .= '&nbsp;(<img src="' . w2PfindImage('icons/priority-' . -$task->task_priority . '.gif') . '" width="13" height="16" alt="" />)';
  576. } elseif ($task->task_priority > 0) {
  577. $tmp .= '&nbsp;(<img src="' . w2PfindImage('icons/priority+' . $task->task_priority . '.gif') . '" width="13" height="16" alt="" />)';
  578. }
  579. $tmp .= '</td>';
  580. $tmp .= '<td align="left">';
  581. $tmp .= '<a href="?m=projects&a=view&project_id=' . $task->task_project . '" style="background-color:#' . $project['project_color_identifier'] . '; color:' . bestColor($project['project_color_identifier']) . '">' . $project['project_name'] . '</a>';
  582. $tmp .= '</td>';
  583. $tmp .= $htmlHelper->createCell('task_duration', $task->task_duration . ' ' . mb_substr($AppUI->_($durnTypes[$task->task_duration_type]), 0, 1));
  584. $tmp .= $htmlHelper->createCell('task_start_date', $task->task_start_date);
  585. $tmp .= $htmlHelper->createCell('task_end_date', $task->task_end_date);
  586. if ($display_week_hours) {
  587. $tmp .= displayWeeks($list, $task, $level, $fromPeriod, $toPeriod);
  588. }
  589. $tmp .= '<td>';
  590. $sep = $us = '';
  591. foreach ($users as $notUsed => $row) {
  592. if ($row['user_id']) {
  593. $us .= '<a href="?m=users&a=view&user_id=' . $row[0] . '">' . $sep . $row['contact_name'] . '&nbsp;(' . $row['perc_assignment'] . '%)</a>';
  594. $sep = ', ';
  595. }
  596. }
  597. $tmp .= $us;
  598. $tmp .= '</td>';
  599. // create the list of possible assignees
  600. $size = (count($active_users) > 5) ? 5 : 3;
  601. $tmp .= '<td valign="top" align="center" nowrap="nowrap">';
  602. $tmp .= '<select name="add_users" style="width:200px" size="'.$size.'" class="text" multiple="multiple" ondblclick="javascript:chAssignment(' . $user_id . ', 0, false)">';
  603. foreach ($active_users as $id => $name) {
  604. $tmp .= '<option value="' . $id . '">' . $name . '</option>';
  605. }
  606. $tmp .= '</select>';
  607. $tmp .= '</td>';
  608. $tmp .= '</tr>';
  609. return $tmp;
  610. }
  611. // from modules/reports/tasksperuser.php
  612. function displayTask_r($list, $task, $level, $display_week_hours, $fromPeriod, $toPeriod, $log_all_projects = false, $user_id = 0)
  613. {
  614. global $AppUI;
  615. $htmlHelper = new w2p_Output_HTMLHelper($AppUI);
  616. $tmp = '';
  617. $tmp .= '<tr><td align="left" nowrap="nowrap">&#160&#160&#160';
  618. for ($i = 0; $i < $level; $i++) {
  619. $tmp .= '&#160&#160&#160';
  620. }
  621. if ($level == 0) {
  622. $tmp .= '<b>';
  623. } elseif ($level == 1) {
  624. $tmp .= '<i>';
  625. }
  626. $tmp .= $task->task_name;
  627. if ($level == 0) {
  628. $tmp .= '</b>';
  629. } elseif ($level == 1) {
  630. $tmp .= '</i>';
  631. }
  632. $tmp .= '&#160&#160&#160</td>';
  633. if ($log_all_projects) {
  634. //Show project name when we are logging all projects
  635. $project = $task->getProject();
  636. $tmp .= '<td nowrap="nowrap">';
  637. if (!isChildTask($task)) {
  638. //However only show the name on parent tasks and not the children to make it a bit cleaner
  639. $tmp .= $project['project_name'];
  640. }
  641. $tmp .= '</td>';
  642. }
  643. $tmp .= $htmlHelper->createCell('task_start_date', $task->task_start_date);
  644. $tmp .= $htmlHelper->createCell('task_end_date', $task->task_end_date);
  645. if ($display_week_hours) {
  646. $tmp .= displayWeeks_r($list, $task, $level, $fromPeriod, $toPeriod, $user_id);
  647. }
  648. $tmp .= "</tr>\n";
  649. return $tmp;
  650. }
  651. // from modules/tasks/tasksperuser_sub.php
  652. function isChildTask($task)
  653. {
  654. return $task->task_id != $task->task_parent;
  655. }
  656. // from modules/tasks/tasksperuser_sub.php
  657. function weekDates($display_allocated_hours, $fromPeriod, $toPeriod)
  658. {
  659. if ($fromPeriod == -1) {
  660. return '';
  661. }
  662. if (!$display_allocated_hours) {
  663. return '';
  664. }
  665. $s = new w2p_Utilities_Date($fromPeriod);
  666. $e = new w2p_Utilities_Date($toPeriod);
  667. $sw = getBeginWeek($s);
  668. $dw = ceil($e->dateDiff($s) / 7);
  669. $ew = $sw + $dw;
  670. $row = '';
  671. for ($i = $sw; $i <= $ew; $i++) {
  672. $wn = $s->getWeekofYear() % 52;
  673. $wn = ($wn != 0) ? $wn : 52;
  674. $row .= '<th title="' . $s->getYear() . '" nowrap="nowrap">' . $wn . '</th>';
  675. $s->addSeconds(168 * 3600); // + one week
  676. }
  677. return $row;
  678. }
  679. // from modules/reports/tasksperuser.php
  680. function weekDates_r($display_allocated_hours, $fromPeriod, $toPeriod)
  681. {
  682. global $AppUI;
  683. if ($fromPeriod == -1) {
  684. return '';
  685. }
  686. if (!$display_allocated_hours) {
  687. return '';
  688. }
  689. $s = new w2p_Utilities_Date($fromPeriod);
  690. $e = new w2p_Utilities_Date($toPeriod);
  691. $sw = getBeginWeek($s);
  692. $ew = getEndWeek($e);
  693. $row = '';
  694. for ($i = $sw; $i <= $ew; $i++) {
  695. $sdf = substr($AppUI->getPref('SHDATEFORMAT'), 3);
  696. $row .= '<td nowrap="nowrap" bgcolor="#A0A0A0"><font color="black"><b>' . $s->format($sdf) . '</b></font></td>';
  697. $s->addSeconds(168 * 3600); // + one week
  698. }
  699. return $row;
  700. }
  701. // from modules/tasks/tasksperuser_sub.php
  702. function weekCells($display_allocated_hours, $fromPeriod, $toPeriod)
  703. {
  704. if ($fromPeriod == -1) {
  705. return 0;
  706. }
  707. if (!$display_allocated_hours) {
  708. return 0;
  709. }
  710. $s = new w2p_Utilities_Date($fromPeriod);
  711. $e = new w2p_Utilities_Date($toPeriod);
  712. $sw = getBeginWeek($s);
  713. $dw = ceil($e->dateDiff($s) / 7);
  714. $ew = $sw + $dw;
  715. return $ew - $sw + 1;
  716. }
  717. // from modules/reports/tasksperuser.php
  718. function weekCells_r($display_allocated_hours, $fromPeriod, $toPeriod)
  719. {
  720. if ($fromPeriod == -1) {
  721. return 0;
  722. }
  723. if (!$display_allocated_hours) {
  724. return 0;
  725. }
  726. $s = new w2p_Utilities_Date($fromPeriod);
  727. $e = new w2p_Utilities_Date($toPeriod);
  728. $sw = getBeginWeek($s);
  729. $ew = getEndWeek($e);
  730. return $ew - $sw + 1;
  731. }
  732. // from modules/tasks/tasksperuser_sub.php
  733. // Look for a user when he/she has been allocated
  734. // to this task and when. Report this in weeks
  735. // This function is called within 'displayTask()'
  736. function displayWeeks($list, $task, $level, $fromPeriod, $toPeriod)
  737. {
  738. if ($fromPeriod == -1) {
  739. return '';
  740. }
  741. $s = new w2p_Utilities_Date($fromPeriod);
  742. $e = new w2p_Utilities_Date($toPeriod);
  743. $sw = getBeginWeek($s);
  744. $dw = ceil($e->dateDiff($s) / 7);
  745. $ew = $sw + $dw;
  746. $st = new w2p_Utilities_Date($task->task_start_date);
  747. $et = new w2p_Utilities_Date($task->task_end_date);
  748. $stw = getBeginWeek($st);
  749. $dtw = ceil($et->dateDiff($st) / 7);
  750. $etw = $stw + $dtw;
  751. $row = '';
  752. for ($i = $sw; $i <= $ew; $i++) {
  753. if ($i >= $stw and $i < $etw) {
  754. $color = 'blue';
  755. if ($level == 0 and hasChildren($list, $task)) {
  756. $color = '#C0C0FF';
  757. } elseif ($level == 1 and hasChildren($list, $task)) {
  758. $color = '#9090FF';
  759. }
  760. $row .= '<td nowrap="nowrap" bgcolor="' . $color . '">';
  761. } else {
  762. $row .= '<td nowrap="nowrap">';
  763. }
  764. $row .= '&#160&#160</td>';
  765. }
  766. return $row;
  767. }
  768. // Look for a user when he/she has been allocated
  769. // to this task and when. Report this in weeks
  770. // This function is called within 'displayTask_r()'
  771. // from modules/reports/tasksperuser.php
  772. function displayWeeks_r($list, $task, $level, $fromPeriod, $toPeriod, $user_id = 0)
  773. {
  774. if ($fromPeriod == -1) {
  775. return '';
  776. }
  777. $s = new w2p_Utilities_Date($fromPeriod);
  778. $e = new w2p_Utilities_Date($toPeriod);
  779. $sw = getBeginWeek($s);
  780. $ew = getEndWeek($e);
  781. $st = new w2p_Utilities_Date($task->task_start_date);
  782. $et = new w2p_Utilities_Date($task->task_end_date);
  783. $stw = getBeginWeek($st);
  784. $etw = getEndWeek($et);
  785. $row = '';
  786. for ($i = $sw; $i <= $ew; $i++) {
  787. $assignment = '';
  788. if ($i >= $stw and $i < $etw) {
  789. $color = '#0000FF';
  790. if ($level == 0 and hasChildren($list, $task)) {
  791. $color = '#C0C0FF';
  792. } elseif ($level == 1 and hasChildren($list, $task)) {
  793. $color = '#9090FF';
  794. }
  795. if ($user_id) {
  796. $users = $task->getAssignedUsers($task->task_id);
  797. $assignment = ($users[$user_id]['perc_assignment']) ? $users[$user_id]['perc_assignment'].'%' : '';
  798. }
  799. } else {
  800. $color = '#FFFFFF';
  801. }
  802. $row .= '<td bgcolor="' . $color . '" class="center">';
  803. $row .= '<font color="'.bestColor($color).'">';
  804. $row .= $assignment;
  805. $row .= '</font>';
  806. $row .= '</td>';
  807. }
  808. return $row;
  809. }
  810. // from modules/tasks/tasksperuser_sub.php
  811. // from modules/reports/tasksperuser.php
  812. function getBeginWeek($d)
  813. {
  814. $dn = (int) $d->Format('%w');
  815. $dd = new w2p_Utilities_Date($d);
  816. $dd->subtractSeconds($dn * 24 * 3600);
  817. return (int) $dd->Format('%U');
  818. }
  819. // from modules/tasks/tasksperuser_sub.php
  820. // from modules/reports/tasksperuser.php
  821. function getEndWeek($d)
  822. {
  823. $dn = (int) $d->Format('%w');
  824. if ($dn > 0) {
  825. $dn = 7 - $dn;
  826. }
  827. $dd = new w2p_Utilities_Date($d);
  828. $dd->addSeconds($dn * 24 * 3600);
  829. return (int) $dd->Format('%U');
  830. }
  831. // from modules/tasks/tasksperuser_sub.php
  832. // from modules/reports/tasksperuser.php
  833. function hasChildren($list, $task)
  834. {
  835. foreach ($list as $t) {
  836. if ($t->task_parent == $task->task_id) {
  837. return true;
  838. }
  839. }
  840. return false;
  841. }
  842. // from modules/tasks/tasksperuser_sub.php
  843. function getOrphanedTasks($tval)
  844. {
  845. return (sizeof($tval->task_assigned_users) > 0) ? null : $tval;
  846. }
  847. // from modules/tasks/viewgantt.php
  848. function showfiltertask(&$a, $level=0)
  849. {
  850. /* Add tasks to the filter task aray */
  851. global $filter_task_list, $parents;
  852. $filter_task_list[] = array($a, $level);
  853. $parents[$a['task_parent']] = true;
  854. }
  855. // from modules/tasks/viewgantt.php
  856. function findfiltertaskchild(&$tarr, $parent, $level=0)
  857. {
  858. $level++;
  859. $n = count($tarr);
  860. for ($x=0; $x < $n; $x++) {
  861. if ($tarr[$x]['task_parent'] == $parent && $tarr[$x]['task_parent'] != $tarr[$x]['task_id']) {
  862. showfiltertask($tarr[$x], $level);
  863. findfiltertaskchild($tarr, $tarr[$x]['task_id'], $level);
  864. }
  865. }
  866. }
  867. // from modules/system/roles/roles.class.php
  868. function showRoleRow($role = null)
  869. {
  870. global $canEdit, $canDelete, $role_id, $AppUI, $roles;
  871. $id = $role['id'];
  872. $name = $role['value'];
  873. $description = $role['name'];
  874. if (!$id) {
  875. $roles_arr = array(0 => '(' . $AppUI->_('Copy Role') . '...)');
  876. foreach ($roles as $role) {
  877. $roles_arr[$role['id']] = $role['name'];
  878. }
  879. }
  880. $s = '';
  881. if (($role_id == $id || $id == 0) && $canEdit) {
  882. // edit form
  883. $s .= '<form name="roleFrm" method="post" action="?m=system&u=roles" accept-charset="utf-8">';
  884. $s .= '<input type="hidden" name="dosql" value="do_role_aed" />';
  885. $s .= '<input type="hidden" name="del" value="0" />';
  886. $s .= '<input type="hidden" name="role_id" value="' . $id . '" />';
  887. $s .= '<tr><td>&nbsp;</td>';
  888. $s .= '<td valign="top"><input type="text" size="20" name="role_name" value="' . $name . '" class="text" /></td>';
  889. $s .= '<td valign="top"><input type="text" size="50" name="role_description" class="text" value="' . $description . '">' . ($id ? '' : '&nbsp;&nbsp;&nbsp;&nbsp;' . arraySelect($roles_arr, 'copy_role_id', 'class="text"', 0, true));
  890. $s .= '<input type="submit" value="' . $AppUI->_($id ? 'save' : 'add') . '" class="button btn btn-primary btn-mini right" /></td>';
  891. } else {
  892. $s .= '<tr><td width="50" valign="top">';
  893. if ($canEdit) {
  894. $s .= '<a href="?m=system&u=roles&role_id=' . $id . '">' . w2PshowImage('icons/stock_edit-16.png') . '</a><a href="?m=system&u=roles&a=viewrole&role_id=' . $id . '" title="">' . w2PshowImage('obj/lock.gif') . '</a>';
  895. }
  896. if ($canDelete && strpos($name, 'admin') === false) {
  897. $s .= '<a href=\'javascript:delIt(' . $id . ')\'>' . w2PshowImage('icons/stock_delete-16.png') . '</a>';
  898. }
  899. $s .= '</td><td valign="top">' . $name . '</td><td valign="top">' . $AppUI->_($description) . '</td>';
  900. }
  901. $s .= '</tr>';
  902. return $s;
  903. }
  904. // from modules/system/syskeys/syskeys.class.php
  905. function parseFormatSysval($text, $syskey)
  906. {
  907. $q = new w2p_Database_Query;
  908. $q->addTable('syskeys');
  909. $q->addQuery('syskey_type, syskey_sep1, syskey_sep2');
  910. $q->addWhere('syskey_id = ' . (int) $syskey);
  911. $q->exec();
  912. $row = $q->fetchRow();
  913. $q->clear();
  914. // type 0 = list
  915. $sep1 = $row['syskey_sep1']; // item separator
  916. $sep2 = $row['syskey_sep2']; // alias separator
  917. // A bit of magic to handle newlines and returns as separators
  918. // Missing sep1 is treated as a newline.
  919. if (!isset($sep1) || empty($sep1)) {
  920. $sep1 = "\n";
  921. }
  922. if ($sep1 == "\\n") {
  923. $sep1 = "\n";
  924. }
  925. if ($sep1 == "\\r") {
  926. $sep1 = "\r";
  927. }
  928. $temp = explode($sep1, $text);
  929. $arr = array();
  930. // We use trim() to make sure a numeric that has spaces
  931. // is properly treated as a numeric
  932. foreach ($temp as $item) {
  933. if ($item) {
  934. $sep2 = empty($sep2) ? "\n" : $sep2;
  935. $temp2 = explode($sep2, $item);
  936. if (isset($temp2[1])) {
  937. $arr[mb_trim($temp2[0])] = mb_trim($temp2[1]);
  938. } else {
  939. $arr[mb_trim($temp2[0])] = mb_trim($temp2[0]);
  940. }
  941. }
  942. }
  943. return $arr;
  944. }
  945. // from modules/system/billingcode.php
  946. function showcodes(&$a)
  947. {
  948. global $AppUI, $company_id;
  949. $s = '
  950. <tr>
  951. <td width=40>
  952. <a href="?m=system&amp;a=billingcode&amp;company_id=' . $company_id . '&amp;billingcode_id=' . $a['billingcode_id'] . '" title="' . $AppUI->_('edit') . '">
  953. <img src="' . w2PfindImage('icons/stock_edit-16.png') . '" alt="Edit" /></a>';
  954. if ($a['billingcode_status'] == 0)
  955. $s .= '<a href="javascript:delIt2(' . $a['billingcode_id'] . ');" title="' . $AppUI->_('delete') . '">
  956. <img src="' . w2PfindImage('icons/stock_delete-16.png') . '" alt="Delete" /></a>';
  957. $s .= '
  958. </td>
  959. <td align="left">&nbsp;' . $a['billingcode_name'] . ($a['billingcode_status'] == 1 ? ' (deleted)' : '') . '</td>
  960. <td nowrap="nowrap" align="center">' . $a['billingcode_value'] . '</td>
  961. <td nowrap="nowrap">' . $a['billingcode_desc'] . '</td>
  962. </tr>';
  963. return $s;
  964. }
  965. // from modules/smartsearch/smartsearch.class.php
  966. function highlight($text, $keyval)
  967. {
  968. global $ssearch;
  969. $txt = $text;
  970. $keys = (!is_array($keyval)) ? array($keyval) : $keyval;
  971. foreach ($keys as $key_idx => $key) {
  972. if (mb_strlen($key) > 0) {
  973. $key = stripslashes($key);
  974. $metacharacters = array('\\', '(', ')', '$', '[', '*', '+', '|', '.', '^', '?');
  975. $metareplacement = array('\\\\', '\(', '\)', '\$', '\[', '\*', '\+', '\|', '\.', '\^', '\?');
  976. $key = mb_str_replace($metacharacters, $metareplacement, $key);
  977. if (isset($ssearch['ignore_specchar']) && ($ssearch['ignore_specchar'] == 'on')) {
  978. if ($ssearch['ignore_case'] == 'on') {
  979. $txt = preg_replace('/'.recode2regexp_utf8($key).'/i', '<span class="highlight' . $key_idx . '" >\\0</span>', $txt);
  980. } else {
  981. $txt = preg_replace('/'.(recode2regexp_utf8($key)).'/', '<span class="highlight' . $key_idx . '" >\\0</span>', $txt);
  982. }
  983. } elseif (!isset($ssearch['ignore_specchar']) || ($ssearch['ignore_specchar'] == '')) {
  984. if ($ssearch['ignore_case'] == 'on') {
  985. $txt = preg_replace('/'.$key.'/i', '<span class="highlight' . $key_idx . '" >\\0</span>', $txt);
  986. } else {
  987. $txt = preg_replace('/'.$key.'/', '<span class="highlight' . $key_idx . '" >\\0</span>', $txt);
  988. }
  989. } else {
  990. $txt = preg_replace('/'.$key.'/i', '<span class="highlight:' . $key_idx . '" >\\0</span>', $txt);
  991. }
  992. }
  993. }
  994. return $txt;
  995. }
  996. // from modules/smartsearch/smartsearch.class.php
  997. function recode2regexp_utf8($input)
  998. {
  999. $result = '';
  1000. for ($i = 0, $i_cmp = mb_strlen($input); $i < $i_cmp; ++$i)
  1001. switch ($input[$i]) {
  1002. case 'A':
  1003. case 'a':
  1004. $result .= '(a|A!|A�|A?|A�)';
  1005. break;
  1006. case 'C':
  1007. case 'c':
  1008. $result .= '(c|�?|�O)';
  1009. break;
  1010. case 'D':
  1011. case 'd':
  1012. $result .= '(d|�?|Ď)';
  1013. break;
  1014. case 'E':
  1015. case 'e':
  1016. $result .= '(e|A�|ě|A�|Ě)';
  1017. break;
  1018. case 'I':
  1019. case 'i':
  1020. $result .= '(i|A�|A?)';
  1021. break;
  1022. case 'L':
  1023. case 'l':
  1024. $result .= '(l|�o|�3|�1|�1)';
  1025. break;
  1026. case 'N':
  1027. case 'n':
  1028. $result .= '(n|A^|A�)';
  1029. break;
  1030. case 'O':
  1031. case 'o':
  1032. $result .= '(o|A3|A�|A�|A�)';
  1033. break;
  1034. case 'R':
  1035. case 'r':
  1036. $result .= '(r|A�|A�|A�|A~)';
  1037. break;
  1038. case 'S':
  1039. case 's':
  1040. $result .= '(s|A!|A�)';
  1041. break;
  1042. case 'T':
  1043. case 't':
  1044. $result .= '(t|AY|A�)';
  1045. break;
  1046. case 'U':
  1047. case 'u':
  1048. $result .= '(u|Ao|A�|A�|A�)';
  1049. break;
  1050. case 'Y':
  1051. case 'y':
  1052. $result .= '(y|A1|A?)';
  1053. break;
  1054. case 'Z':
  1055. case 'z':
  1056. $result .= '(z|A3|A1)';
  1057. break;
  1058. default:
  1059. $result .= $input[$i];
  1060. }
  1061. return $result;
  1062. }
  1063. // from modules/public/selector.php
  1064. function selPermWhere($obj, $idfld, $namefield, $prefix = '')
  1065. {
  1066. global $AppUI;
  1067. $allowed = $obj->getAllowedRecords($AppUI->user_id, $idfld . ', ' . $namefield, '', '', '', $prefix);
  1068. if (count($allowed)) {
  1069. return ' ' . $idfld . ' IN (' . implode(',', array_keys($allowed)) . ') ';
  1070. } else {
  1071. return null;
  1072. }
  1073. }
  1074. //comes from modules/departments/departments.class.php
  1075. //writes out a single <option> element for display of departments
  1076. function showchilddept(&$a, $level = 1)
  1077. {
  1078. global $department;
  1079. $s = '<option value="' . $a['dept_id'] . '"' . (isset($department) && $department == $a['dept_id'] ? 'selected="selected"' : '') . '>';
  1080. for ($y = 0; $y < $level; $y++) {
  1081. if ($y + 1 == $level) {
  1082. $s .= '';
  1083. } else {
  1084. $s .= '&nbsp;&nbsp;';
  1085. }
  1086. }
  1087. $s .= '&nbsp;&nbsp;' . $a['dept_name'] . '</option>';
  1088. return $s;
  1089. }
  1090. //comes from modules/departments/departments.class.php
  1091. //recursive function to display children departments.
  1092. function findchilddept(&$tarr, $parent, $level = 1)
  1093. {
  1094. $level++;
  1095. $n = count($tarr);
  1096. for ($x = 0; $x < $n; $x++) {
  1097. if ($tarr[$x]['dept_parent'] == $parent && $tarr[$x]['dept_parent'] != $tarr[$x]['dept_id']) {
  1098. findchilddept($tarr, $tarr[$x]['dept_id'], $level);
  1099. }
  1100. }
  1101. }
  1102. //comes from modules/departments/departments.class.php
  1103. function addDeptId($dataset, $parent)
  1104. {
  1105. global $dept_ids;
  1106. foreach ($dataset as $data) {
  1107. if ($data['dept_parent'] == $parent) {
  1108. $dept_ids[] = $data['dept_id'];
  1109. addDeptId($dataset, $data['dept_id']);
  1110. }
  1111. }
  1112. }
  1113. // From: modules/files/filefolder.class.php
  1114. function getFolderSelectList()
  1115. {
  1116. global $AppUI;
  1117. $q = new w2p_Database_Query();
  1118. $q->addTable('file_folders');
  1119. $q->addQuery('file_folder_id, file_folder_name, file_folder_parent');
  1120. $q->addOrder('file_folder_name');
  1121. $folderList = $q->loadHashList('file_folder_id');
  1122. $folders = array(0 => 'Root');
  1123. foreach($folderList as $folder => $data) {
  1124. $folders[$folder] = $data['file_folder_name'];
  1125. }
  1126. return $folders;
  1127. }
  1128. /*
  1129. * $parent is the parent of the children we want to see
  1130. * $level is increased when we go deeper into the tree, used to display a nice indented tree
  1131. */
  1132. // From: modules/files/filefolder.class.php
  1133. function getFolders($parent)
  1134. {
  1135. global $AppUI, $allowed_folders_ary, $tab, $m, $a, $company_id, $project_id, $task_id;
  1136. // retrieve all children of $parent
  1137. $file_folder = new CFile_Folder();
  1138. $folders = $file_folder->getFoldersByParent($parent);
  1139. $s = '';
  1140. // display each child
  1141. foreach ($folders as $row) {
  1142. if (array_key_exists($row['file_folder_id'], $allowed_folders_ary) or array_key_exists($parent, $allowed_folders_ary)) {
  1143. $file_count = countFiles($row['file_folder_id']);
  1144. $s .= '<tr><td colspan="20">';
  1145. $s .= '<ul>';
  1146. $s .= '<li><a href="./index.php?m=files&amp;a=addedit_folder&amp;file_folder_parent=' . $row['file_folder_id'] . '&amp;file_folder_id=0">' . w2PshowImage('edit_add.png', '', '', 'new folder', 'add a new subfolder', 'files') . '</a></li>';
  1147. $s .= '<li><a href="./index.php?m=files&amp;a=addedit&amp;folder=' . $row['file_folder_id'] . '&amp;project_id=' . $project_id . '&amp;file_id=0">' . w2PshowImage('folder_new.png', '', '', 'new file', 'add new file to this folder', 'files') . '</a></li>';
  1148. $s .= '<li><a href="./index.php?m=files&amp;a=addedit_folder&amp;folder=' . $row['file_folder_id'] . '">' . w2PshowImage('filesaveas.png', '', '', 'edit icon', 'edit this folder', 'files') . '</a></li>';
  1149. if ($m == 'files') {
  1150. $s .= '<li class="info-text"><a href="./index.php?m=' . $m . '&amp;a=' . $a . '&amp;tab=' . $tab . '&folder=' . $row['file_folder_id'] . '" name="ff' . $row['file_folder_id'] . '">';
  1151. }
  1152. $s .= w2PshowImage('folder5_small.png', '22', '22', '', '', 'files');
  1153. $s .= $row['file_folder_name'];
  1154. if ($m == 'files') {
  1155. $s .= '</a></li>';
  1156. }
  1157. if ($file_count > 0) {
  1158. $s .= '<li class="info-text"><a href="javascript: void(0);" onClick="expand(\'files_' . $row['file_folder_id'] . '\')" class="has-files">(' . $file_count . ' files) +</a></li>';
  1159. }
  1160. $s .= '<form name="frm_remove_folder_' . $row['file_folder_id'] . '" action="?m=files" method="post" accept-charset="utf-8">
  1161. <input type="hidden" name="dosql" value="do_folder_aed" />
  1162. <input type="hidden" name="del" value="1" />
  1163. <input type="hidden" name="file_folder_id" value="' . $row['file_folder_id'] . '" />
  1164. </form>';
  1165. $s .= '</ul>';
  1166. $s .= '<a class="small-delete" href="javascript: void(0);" onclick="if (confirm(\'Are you sure you want to delete this folder?\')) {document.frm_remove_folder_' . $row['file_folder_id'] . '.submit()}">' . w2PshowImage('remove.png', '', '', 'delete icon', 'delete this folder', 'files') . '</a>';
  1167. $s .= '</td></tr>';
  1168. if ($file_count > 0) {
  1169. $s .= '<div class="files-list" id="files_' . $row['file_folder_id'] . '" style="display: none;">';
  1170. $s .= displayFiles($AppUI, $row['file_folder_id'], $task_id, $project_id, $company_id);
  1171. $s .= "</div>";
  1172. }
  1173. }
  1174. }
  1175. return $s;
  1176. }
  1177. // From: modules/files/filefolder.class.php
  1178. function countFiles($folder)
  1179. {
  1180. global $company_id, $allowed_companies;
  1181. global $deny1, $deny2, $project_id, $task_id;
  1182. $q = new w2p_Database_Query();
  1183. $q->addTable('files');
  1184. $q->addQuery('count(files.file_id)');
  1185. $q->addJoin('projects', 'p', 'p.project_id = file_project');
  1186. $q->addJoin('users', 'u', 'u.user_id = file_owner');
  1187. $q->addJoin('tasks', 't', 't.task_id = file_task');
  1188. $q->addJoin('file_folders', 'ff', 'ff.file_folder_id = file_folder');
  1189. $q->addWhere('file_folder = ' . (int) $folder);
  1190. if (count($deny1) > 0) {
  1191. $q->addWhere('file_project NOT IN (' . implode(',', $deny1) . ')');
  1192. }
  1193. if (count($deny2) > 0) {
  1194. $q->addWhere('file_task NOT IN (' . implode(',', $deny2) . ')');
  1195. }
  1196. if ($project_id) {
  1197. $q->addWhere('file_project = ' . (int) $project_id);
  1198. }
  1199. if ($task_id) {
  1200. $q->addWhere('file_task = ' . (int) $task_id);
  1201. }
  1202. if ($company_id) {
  1203. $q->innerJoin('companies', 'co', 'co.company_id = p.project_company');
  1204. $q->addWhere('company_id = ' . (int) $company_id);
  1205. $q->addWhere('company_id IN (' . $allowed_companies . ')');
  1206. }
  1207. $files_in_folder = $q->loadResult();
  1208. $q->clear();
  1209. return $files_in_folder;
  1210. }
  1211. // From: modules/files/filefolder.class.php
  1212. function displayFiles($AppUI, $folder_id, $task_id, $project_id, $company_id)
  1213. {
  1214. global $m, $tab, $xpg_min, $xpg_pagesize, $showProject, $file_types,
  1215. $company_id, $current_uri, $canEdit;
  1216. // SETUP FOR FILE LIST
  1217. $q = new w2p_Database_Query();
  1218. $q->addQuery('f.*, max(f.file_id) as latest_id, count(f.file_version) as file_versions, round(max(file_version), 2) as file_lastversion, file_owner, user_id');
  1219. $q->addQuery('ff.*, max(file_version) as file_version, f.file_date as file_datetime');
  1220. $q->addTable('files', 'f');
  1221. $q->addJoin('file_folders', 'ff', 'ff.file_folder_id = file_folder');
  1222. $q->addJoin('projects', 'p', 'p.project_id = file_project');
  1223. $q->addJoin('tasks', 't', 't.task_id = file_task');
  1224. $q->addJoin('users', 'u', 'u.user_id = file_owner');
  1225. $q->leftJoin('project_departments', 'project_departments', 'p.project_id = project_departments.project_id OR project_departments.project_id IS NULL');
  1226. $q->leftJoin('departments', 'departments', 'departments.dept_id = project_departments.department_id OR dept_id IS NULL');
  1227. //TODO: apply permissions properly
  1228. $project = new CProject();
  1229. $deny1 = $project->getDeniedRecords($AppUI->user_id);
  1230. if (count($deny1) > 0) {
  1231. $q->addWhere('file_project NOT IN (' . implode(',', $deny1) . ')');
  1232. }
  1233. //TODO: apply permissions properly
  1234. $task = new CTask();
  1235. $deny2 = $task->getDeniedRecords($AppUI->user_id);
  1236. if (count($deny2) > 0) {
  1237. $q->addWhere('file_task NOT IN (' . implode(',', $deny2) . ')');
  1238. }
  1239. if ($project_id) {
  1240. $q->addWhere('file_project = ' . (int) $project_id);
  1241. }
  1242. if ($task_id) {
  1243. $q->addWhere('file_task = ' . (int) $task_id);
  1244. }
  1245. if ($company_id) {
  1246. $q->addWhere('project_company = ' . (int) $company_id);
  1247. }
  1248. //$tab = ($m == 'files') ? $tab-1 : -1;
  1249. $temp_tab = ($m == 'files') ? $tab - 1 : -1;
  1250. if (($temp_tab >= 0) and ((count($file_types) - 1) > $temp_tab)) {
  1251. //if ($tab >= 0) {
  1252. $q->addWhere('file_category = ' . (int) $temp_tab);
  1253. }
  1254. $q->setLimit($xpg_pagesize, $xpg_min);
  1255. if ($folder_id > -1) {
  1256. $q->addWhere('file_folder = ' . (int) $folder_id);
  1257. }
  1258. $q->addGroup('file_version_id DESC');
  1259. $q->addOrder('project_name ASC, file_parent ASC, file_id DESC');
  1260. $qv = new w2p_Database_Query();
  1261. $qv->addTable('files');
  1262. $qv->addQuery('file_id, file_version, file_project, file_name, file_task,
  1263. file_description, file_owner, file_size, file_category,
  1264. task_name, file_version_id, file_date as file_datetime, file_checkout, file_co_reason, file_type,
  1265. file_date, cu.user_username as co_user, project_name,
  1266. project_color_identifier, project_owner, u.user_id,
  1267. con.contact_first_name, con.contact_last_name, con.contact_display_name as contact_name,
  1268. co.contact_first_name as co_contact_first_name, co.contact_last_name as co_contact_last_name,
  1269. co.contact_display_name as co_contact_name ');
  1270. $qv->addJoin('projects', 'p', 'p.project_id = file_project');
  1271. $qv->addJoin('users', 'u', 'u.user_id = file_owner');
  1272. $qv->addJoin('contacts', 'con', 'con.contact_id = u.user_contact');
  1273. $qv->addJoin('tasks', 't', 't.task_id = file_task');
  1274. $qv->addJoin('file_folders', 'ff', 'ff.file_folder_id = file_folder');
  1275. if ($project_id) {
  1276. $qv->addWhere('file_project = ' . (int) $project_id);
  1277. }
  1278. if ($task_id) {
  1279. $qv->addWhere('file_task = ' . (int) $task_id);
  1280. }
  1281. if ($company_id) {
  1282. $qv->addWhere('project_company = ' . (int) $company_id);
  1283. }
  1284. if (($temp_tab >= 0) and ((count($file_types) - 1) > $temp_tab)) {
  1285. //if ($tab >= 0) {
  1286. $qv->addWhere('file_category = ' . (int) $temp_tab);
  1287. }
  1288. $qv->leftJoin('users', 'cu', 'cu.user_id = file_checkout');
  1289. $qv->leftJoin('contacts', 'co', 'co.contact_id = cu.user_contact');
  1290. if ($folder_id > -1) {
  1291. $qv->addWhere('file_folder = ' . (int) $folder_id);
  1292. }
  1293. $files = $q->loadList();
  1294. $file_versions = $qv->loadHashList('file_id');
  1295. $module = new w2p_System_Module();
  1296. $fields = $module->loadSettings('files', 'index_list');
  1297. if (count($fields) > 0) {
  1298. $fieldList = array_keys($fields);
  1299. $fieldNames = array_values($fields);
  1300. } else {
  1301. // TODO: This is only in place to provide an pre-upgrade-safe
  1302. // state for versions earlier than v3.0
  1303. // At some point at/after v4.0, this should be deprecated
  1304. $fieldList = array('file_name', 'file_description',
  1305. 'file_version', 'file_category', 'file_folder', 'file_task',
  1306. 'file_owner', 'file_datetime');
  1307. $fieldNames = array('File Name', 'Description', 'Version', 'Category',
  1308. 'Folder', 'Task Name', 'Owner', 'Date',);
  1309. $module->storeSettings('files', 'index_list', $fieldList, $fieldNames);
  1310. }
  1311. $s = '<tr>';
  1312. $s .= '<th></th>';
  1313. $s .= '<th>' . $AppUI->_('co') . '</th>';
  1314. foreach ($fieldNames as $index => $name) {
  1315. $s .= '<th>' . $AppUI->_($fieldNames[$index]) . '</th>';
  1316. }
  1317. $s .= '<th></th>';
  1318. $s .= '</tr>';
  1319. $fp = -1;
  1320. $htmlHelper = new w2p_Output_HTMLHelper($AppUI);
  1321. $htmlHelper->df .= ' ' . $AppUI->getPref('TIMEFORMAT');
  1322. $file_types = w2PgetSysVal('FileType');
  1323. $customLookups = array('file_category' => $file_types);
  1324. foreach ($files as $row) {
  1325. $latest_file = $file_versions[$row['latest_id']];
  1326. if ($fp != $latest_file['file_project']) {
  1327. if (!$latest_file['file_project']) {
  1328. $latest_file['project_name'] = $AppUI->_('Not attached to a project');
  1329. $latest_file['project_color_identifier'] = 'f4efe3';
  1330. }
  1331. if ($showProject) {
  1332. $style = 'background-color:#' . $latest_file['project_color_identifier'] . ';color:' . bestColor($latest_file['project_color_identifier']);
  1333. $s .= '<tr>';
  1334. $s .= '<td colspan="20" style="text-align: left; border: outset 2px #eeeeee;' . $style . '">';
  1335. if ($latest_file['file_project'] > 0) {
  1336. $href = './index.php?m=projects&a=view&project_id=' . $latest_file['file_project'];
  1337. } else {
  1338. $href = './index.php?m=projects';
  1339. }
  1340. $s .= '<a href="' . $href . '">';
  1341. $s .= '<span style="' . $style . '">' . $latest_file['project_name'] . '</span></a>';
  1342. $s .= '</td></tr>';
  1343. }
  1344. }
  1345. $fp = $latest_file['file_project'];
  1346. $row['file_datetime'] = $latest_file['file_datetime'];
  1347. $row['file_id'] = $latest_file['file_id'];
  1348. $htmlHelper->stageRowData($row);
  1349. $s .= '<tr>';
  1350. $s .= '<td class="data">';
  1351. if ($canEdit && (empty($latest_file['file_checkout']) || ($latest_file['file_checkout'] == 'final' && ($canEdit || $latest_file['project_owner'] == $AppUI->user_id)))) {
  1352. $s .= '<a href="./index.php?m=files&a=addedit&file_id=' . $latest_file['file_id'] . '">' . w2PshowImage('kedit.png', '16', '16', 'edit file', 'edit file', 'files') . '</a>';
  1353. }
  1354. $s .= '</td>';
  1355. $s .= '<td class="data">';
  1356. if ($canEdit && empty($latest_file['file_checkout'])) {
  1357. $s .= '<a href="?m=files&a=co&file_id=' . $latest_file['file_id'] . '">' . w2PshowImage('up.png', '16', '16', 'checkout', 'checkout file', 'files') . '</a>';
  1358. } else {
  1359. if ($latest_file['file_checkout'] == $AppUI->user_id) {
  1360. $s .= '<a href="?m=files&a=addedit&ci=1&file_id=' . $latest_file['file_id'] . '">' . w2PshowImage('down.png', '16', '16', 'checkin', 'checkin file', 'files') . '</a>';
  1361. } else {
  1362. if ($latest_file['file_checkout'] == 'final') {
  1363. $s .= 'final';
  1364. } else {
  1365. $s .= $latest_file['co_contact_name'] . '<br>(' . $latest_file['co_user'] . ')';
  1366. }
  1367. }
  1368. }
  1369. $version_link = '';
  1370. $hidden_table = '';
  1371. if ($row['file_versions'] > 1) {
  1372. $version_link = '&nbsp<a href="javascript: void(0);" onClick="expand(\'versions_' . $latest_file['file_id'] . '\'); ">(' . $row['file_versions'] . ')</a>';
  1373. $hidden_table = '<tr><td colspan="20">
  1374. <table style="display: none" id="versions_' . $latest_file['file_id'] . '" class="tbl list">
  1375. <tr>';
  1376. foreach ($fieldNames as $index => $name) {
  1377. $hidden_table .= '<th nowrap="nowrap">';
  1378. $hidden_table .= $AppUI->_($fieldNames[$index]);
  1379. $hidden_table .= '</th>';
  1380. }
  1381. $hidden_table .= '</tr>';
  1382. $sub_htmlHelper = new w2p_Output_HTMLHelper($AppUI);
  1383. $sub_htmlHelper->df .= ' ' . $AppUI->getPref('TIMEFORMAT');
  1384. foreach ($file_versions as $file) {
  1385. $sub_htmlHelper->stageRowData($file);
  1386. if ($file['file_version_id'] == $latest_file['file_version_id']) {
  1387. foreach ($fieldList as $index => $column) {
  1388. $hidden_table .= $sub_htmlHelper->createCell($fieldList[$index], $file[$fieldList[$index]], $customLookups);
  1389. }
  1390. if ($canEdit && w2PgetConfig('files_show_versions_edit')) {
  1391. $hidden_table .= '<a href="./index.php?m=files&a=addedit&file_id=' . $file['file_id'] . '">' . w2PshowImage('kedit.png', '16', '16', 'edit file', 'edit file', 'files') . "</a>";
  1392. }
  1393. $hidden_table .= '</td><tr>';
  1394. }
  1395. }
  1396. $hidden_table .= '</table>';
  1397. }
  1398. $s .= '</td>';
  1399. foreach ($fieldList as $index => $column) {
  1400. $cell = $htmlHelper->createCell($fieldList[$index], $row[$fieldList[$index]], $customLookups);
  1401. if ('file_version' == $fieldList[$index]) {
  1402. $cell = str_replace('</td>', $version_link.'</td>', $cell);
  1403. }
  1404. $s .= $cell;
  1405. }
  1406. $s .= '<td>';
  1407. $s .= '<form name="frm_remove_file_' . $latest_file['file_id'] . '" action="?m=files" method="post" accept-charset="utf-8">
  1408. <input type="hidden" name="dosql" value="do_file_aed" />
  1409. <input type="hidden" name="del" value="1" />
  1410. <input type="hidden" name="file_id" value="' . $latest_file['file_id'] . '" />
  1411. <input type="hidden" name="redirect" value="' . $current_uri . '" />
  1412. </form>';
  1413. $s .= '<a href="javascript: void(0);" onclick="if (confirm(\'' . $AppUI->_('Are you sure you want to delete this file?') . '\')) {document.frm_remove_file_' . $latest_file['file_id'] . '.submit()}">' . w2PshowImage('remove.png', '16', '16', 'delete file', 'delete file', 'files') . '</a>';
  1414. $s .= '</td>';
  1415. $s .= '</tr>';
  1416. $s .= $hidden_table;
  1417. }
  1418. if (0 == count($files)) {
  1419. $s .= '<tr><td colspan="' . (count($fieldNames) + 3 ) . '">' . $AppUI->_('No data available') . '</td></tr>';
  1420. }
  1421. return $s;
  1422. }
  1423. // From: modules/files/files.class.php
  1424. function last_file($file_versions, $file_name, $file_project)
  1425. {
  1426. $latest = null;
  1427. if (isset($file_versions))
  1428. foreach ($file_versions as $file_version)
  1429. if ($file_version['file_name'] == $file_name && $file_version['file_project'] == $file_project)
  1430. if ($latest == null || $latest['file_version'] < $file_version['file_version'])
  1431. $latest = $file_version;
  1432. return $latest;
  1433. }
  1434. // From: modules/files/files.class.php
  1435. function getIcon($file_type)
  1436. {
  1437. global $uistyle;
  1438. $mime = str_replace('/', '-', $file_type);
  1439. $icon = 'gnome-mime-' . $mime;
  1440. if (is_file(W2P_BASE_DIR . '/styles/' . $uistyle . '/images/modules/files/icons/' . $icon . '.png')) {
  1441. $result = 'icons/' . $icon . '.png';
  1442. } else {
  1443. $result = __extract_from_files_index_table($file_type);
  1444. }
  1445. return $result;
  1446. }
  1447. /**
  1448. * @param $file_type
  1449. * @return string
  1450. */
  1451. function __extract_from_files_index_table($file_type)
  1452. {
  1453. $mime = explode('/', $file_type);
  1454. switch ($mime[0]) {
  1455. case 'audio':
  1456. $result = 'icons/wav.png';
  1457. break;
  1458. case 'image':
  1459. $result = 'icons/image.png';
  1460. break;
  1461. case 'text':
  1462. $result = 'icons/text.png';
  1463. break;
  1464. case 'video':
  1465. $result = 'icons/video.png';
  1466. break;
  1467. case 'application':
  1468. switch ($mime[1]) {
  1469. case 'vnd.ms-excel':
  1470. $result = 'icons/spreadsheet.png';
  1471. break;
  1472. case 'vnd.ms-powerpoint':
  1473. $result = 'icons/quicktime.png';
  1474. break;
  1475. case 'octet-stream':
  1476. $result = 'icons/source_c.png';
  1477. break;
  1478. default:
  1479. $result = 'icons/documents.png';
  1480. }
  1481. break;
  1482. }
  1483. return $result;
  1484. }
  1485. // From: modules/files/files.class.php
  1486. function getHelpdeskFolder()
  1487. {
  1488. $q = new w2p_Database_Query();
  1489. $q->addTable('file_folders', 'ff');
  1490. $q->addQuery('file_folder_id');
  1491. $q->addWhere('ff.file_folder_name = \'Helpdesk\'');
  1492. $ffid = $q->loadResult();
  1493. return (int) $ffid;
  1494. }
  1495. // From: modules/files/files.class.php
  1496. function file_show_attr($AppUI, $form)
  1497. {
  1498. global $object, $ci, $canAdmin, $file_project, $file_task, $task_name, $preserve;
  1499. if ($ci) {
  1500. $str_out = '<p>' . $form->addLabel('Minor Revision') . '<input type="Radio" name="revision_type" value="minor" checked /></p>';
  1501. $str_out .= '<p>' . $form->addLabel('Major Revision') . '<input type="Radio" name="revision_type" value="major" />';
  1502. } else {
  1503. $str_out = '<p>' . $form->addLabel('Version');
  1504. }
  1505. if ($ci) {
  1506. $the_value = (strlen($object->file_version) > 0 ? $object->file_version + 0.01 : '1');
  1507. $str_out .= '<input type="hidden" name="file_version" value="' . $the_value . '" />';
  1508. } else {
  1509. $the_value = (strlen($object->file_version) > 0 ? $object->file_version : '1');
  1510. $str_out .= '<input type="text" name="file_version" maxlength="10" size="5" value="' . $the_value . '" class="text" />';
  1511. }
  1512. if ($ci || ($canAdmin && $object->file_checkout == 'final')) {
  1513. $str_out .= '<input type="hidden" name="file_checkout" value="" /><input type="hidden" name="file_co_reason" value="" />';
  1514. }
  1515. $str_out .= '</p>';
  1516. $select_disabled = ' ';
  1517. $onclick_task = ' onclick="popTask()" ';
  1518. if ($ci && $preserve) {
  1519. $select_disabled = ' disabled="disabled" ';
  1520. $onclick_task = ' ';
  1521. // need because when a html is disabled, it's value it's not sent in submit
  1522. $str_out .= '<input type="hidden" name="file_project" value="' . $file_project . '" />';
  1523. $str_out .= '<input type="hidden" name="file_category" value="' . $object->file_category . '" />';
  1524. }
  1525. // Category
  1526. $str_out .= '<p>' . $form->addLabel('Category');
  1527. $str_out .= arraySelect(w2PgetSysVal('FileType'), 'file_category', 'class="text"' . $select_disabled, $object->file_category, true) . '</p>';
  1528. // ---------------------------------------------------------------------------------
  1529. $str_out .= '<p>' . $form->addLabel('Project');
  1530. $str_out .= projectSelectWithOptGroup($AppUI->user_id, 'file_project', 'size="1" class="text"' . $select_disabled, $file_project) . '</p>';
  1531. // ---------------------------------------------------------------------------------
  1532. // Task
  1533. $str_out .= '<p>' . $form->addLabel('Task');
  1534. $str_out .= '<input type="hidden" name="file_task" value="' . $file_task . '" /><input type="text" class="text" name="task_name" value="' . $task_name . '" size="40" disabled /><input type="button" class="button btn btn-primary btn-mini" value="' . $AppUI->_('select task') . '..."' . $onclick_task . '/></p>';
  1535. return ($str_out);
  1536. }
  1537. /** Retrieve tasks with first task_end_dates within given project
  1538. * @param int Project_id
  1539. * @param int SQL-limit to limit the number of returned tasks
  1540. * @return array List of criticalTasks
  1541. */
  1542. //TODO: modules/projectdesigner/projectdesigner.class.php
  1543. function getCriticalTasksInverted($project_id = null, $limit = 1)
  1544. {
  1545. if (!$project_id) {
  1546. $result = array();
  1547. $result[0]['task_end_date'] = '0000-00-00 00:00:00';
  1548. return $result;
  1549. } else {
  1550. $q = new w2p_Database_Query();
  1551. $q->addTable('tasks');
  1552. $q->addWhere('task_project = ' . (int) $project_id . ' AND NOT ISNULL( task_end_date ) AND task_end_date <> \'0000-00-00 00:00:00\'');
  1553. $q->addOrder('task_start_date ASC');
  1554. $q->setLimit($limit);
  1555. return $q->loadList();
  1556. }
  1557. }
  1558. //TODO: modules/projectdesigner/projectdesigner.class.php
  1559. function get_actual_end_date_pd($task_id, $task)
  1560. {
  1561. global $AppUI;
  1562. $q = new w2p_Database_Query();
  1563. $mods = $AppUI->getActiveModules();
  1564. if (!empty($mods['history']) && canView('history')) {
  1565. $q->addQuery('MAX(history_date) as actual_end_date');
  1566. $q->addTable('history');
  1567. $q->addWhere('history_table=\'tasks\' AND history_item=' . $task_id);
  1568. } else {
  1569. $q->addQuery('MAX(task_log_date) AS actual_end_date');
  1570. $q->addTable('task_log');
  1571. $q->addWhere('task_log_task = ' . (int) $task_id);
  1572. }
  1573. $task_log_end_date = $q->loadResult();
  1574. $edate = $task_log_end_date;
  1575. $edate = ($edate > $task->task_end_date || $task->task_percent_complete == 100) ? $edate : $task->task_end_date;
  1576. return $edate;
  1577. }
  1578. /* The next lines of code have resided in projects/index.php before
  1579. ** and have been moved into this 'encapsulated' function
  1580. ** for reusability of that central code.
  1581. **
  1582. ** @date 20060225
  1583. ** @responsible gregorerhardt
  1584. **
  1585. ** E.g. this code is used as well in a tab for the admin/view site
  1586. **
  1587. ** @mixed user_id userId as filter for tasks/projects that are shown, if nothing is specified,
  1588. current viewing user $AppUI->user_id is used.
  1589. */
  1590. // From: modules/projects/project.class.php
  1591. function projects_list_data($user_id = false)
  1592. {
  1593. global $AppUI, $addPwOiD, $buffer, $company, $company_id, $company_prefix,
  1594. $deny, $department, $dept_ids, $orderby, $orderdir,
  1595. $tasks_problems, $owner, $search_text, $project_type;
  1596. $addProjectsWithAssignedTasks = $AppUI->getState('addProjWithTasks') ? $AppUI->getState('addProjWithTasks') : 0;
  1597. // get any records denied from viewing
  1598. $obj = new CProject();
  1599. $deny = $obj->getDeniedRecords($AppUI->user_id);
  1600. // Let's delete temproary tables
  1601. $q = new w2p_Database_Query;
  1602. $q->setDelete('tasks_problems');
  1603. $q->exec();
  1604. $q->clear();
  1605. $q->setDelete('tasks_users');
  1606. $q->exec();
  1607. $q->clear();
  1608. // support task problem logs
  1609. $q->addInsertSelect('tasks_problems');
  1610. $q->addTable('tasks');
  1611. $q->addQuery('task_project, task_log_problem');
  1612. $q->addJoin('task_log', 'tl', 'tl.task_log_task = task_id', 'inner');
  1613. $q->addWhere('task_log_problem = 1');
  1614. $q->addGroup('task_project');
  1615. $tasks_problems = $q->exec();
  1616. $q->clear();
  1617. if ($addProjectsWithAssignedTasks) {
  1618. // support users tasks
  1619. $q->addInsertSelect('tasks_users');
  1620. $q->addTable('tasks');
  1621. $q->addQuery('task_project');
  1622. $q->addQuery('ut.user_id');
  1623. $q->addJoin('user_tasks', 'ut', 'ut.task_id = tasks.task_id');
  1624. if ($user_id) {
  1625. $q->addWhere('ut.user_id = ' . (int) $user_id);
  1626. }
  1627. $q->addOrder('task_end_date DESC');
  1628. $q->addGroup('task_project');
  1629. $q->exec();
  1630. $q->clear();
  1631. }
  1632. // add Projects where the Project Owner is in the given department
  1633. if ($addPwOiD && isset($department)) {
  1634. $q->addTable('users');
  1635. $q->addQuery('user_id');
  1636. $q->addJoin('contacts', 'c', 'c.contact_id = user_contact', 'inner');
  1637. $q->addWhere('c.contact_department = ' . (int) $department);
  1638. $owner_ids = $q->loadColumn();
  1639. $q->clear();
  1640. }
  1641. if (isset($department)) {
  1642. //If a department is specified, we want to display projects from the department, and all departments under that, so we need to build that list of departments
  1643. $dept_ids = array();
  1644. $q->addTable('departments');
  1645. $q->addQuery('dept_id, dept_parent');
  1646. $q->addOrder('dept_parent,dept_name');
  1647. $rows = $q->loadList();
  1648. addDeptId($rows, $department);
  1649. $dept_ids[] = isset($department->dept_id) ? $department->dept_id : 0;
  1650. $dept_ids[] = ($department > 0) ? $department : 0;
  1651. }
  1652. $q->clear();
  1653. // retrieve list of records
  1654. // modified for speed
  1655. // by Pablo Roca (pabloroca@mvps.org)
  1656. // 16 August 2003
  1657. // get the list of permitted companies
  1658. $obj = new CCompany();
  1659. $companies = $obj->getAllowedRecords($AppUI->user_id, 'companies.company_id,companies.company_name', 'companies.company_name');
  1660. if (count($companies) == 0) {
  1661. $companies = array();
  1662. }
  1663. $q->addTable('projects', 'pr');
  1664. $q->addQuery('pr.*, project_scheduled_hours as project_duration,
  1665. project_actual_end_date as project_end_actual,
  1666. company_id, company_name, project_last_task as critical_task,
  1667. tp.task_log_problem, user_username, task_log_problem, u.user_id');
  1668. $fields = w2p_System_Module::getSettings('projects', 'index_list');
  1669. unset($fields['department_list']); // added as an alias below
  1670. foreach ($fields as $field => $notUsed) {
  1671. $q->addQuery($field);
  1672. }
  1673. $q->addQuery('ct.contact_display_name AS owner_name');
  1674. $q->addJoin('companies', 'c', 'c.company_id = pr.project_company');
  1675. $q->addJoin('users', 'u', 'pr.project_owner = u.user_id');
  1676. $q->addJoin('contacts', 'ct', 'ct.contact_id = u.user_contact');
  1677. $q->addJoin('tasks_problems', 'tp', 'pr.project_id = tp.task_project');
  1678. if ($addProjectsWithAssignedTasks) {
  1679. $q->addJoin('tasks_users', 'tu', 'pr.project_id = tu.task_project');
  1680. }
  1681. if (!isset($department) && $company_id > 0 && !$addPwOiD) {
  1682. $q->addWhere('pr.project_company = ' . (int) $company_id);
  1683. }
  1684. if ($project_type > -1) {
  1685. $q->addWhere('pr.project_type = ' . (int) $project_type);
  1686. }
  1687. if (isset($department) && !$addPwOiD) {
  1688. $q->addWhere('project_departments.department_id in ( ' . implode(',', $dept_ids) . ' )');
  1689. }
  1690. if ($user_id && $addProjectsWithAssignedTasks) {
  1691. $q->addWhere('(tu.user_id = ' . (int) $user_id . ' OR pr.project_owner = ' . (int) $user_id . ' )');
  1692. } elseif ($user_id) {
  1693. $q->addWhere('pr.project_owner = ' . (int) $user_id);
  1694. }
  1695. if ($owner > 0) {
  1696. $q->addWhere('pr.project_owner = ' . (int) $owner);
  1697. }
  1698. if (mb_trim($search_text)) {
  1699. $q->addWhere('pr.project_name LIKE \'%' . $search_text . '%\' OR pr.project_description LIKE \'%' . $search_text . '%\'');
  1700. }
  1701. // Show Projects where the Project Owner is in the given department
  1702. if ($addPwOiD && !empty($owner_ids)) {
  1703. $q->addWhere('pr.project_owner IN (' . implode(',', $owner_ids) . ')');
  1704. }
  1705. $orderby = ('project_company' == $orderby) ? 'company_name' : $orderby;
  1706. $q->addGroup('pr.project_id');
  1707. $q->addOrder($orderby . ' ' .$orderdir);
  1708. $prj = new CProject();
  1709. $q = $prj->setAllowedSQL($AppUI->user_id, $q, null, 'pr');
  1710. $dpt = new CDepartment();
  1711. $projects = $q->loadList();
  1712. // get the list of permitted companies
  1713. $companies = arrayMerge(array('0' => $AppUI->_('All')), $companies);
  1714. $company_array = $companies;
  1715. //get list of all departments, filtered by the list of permitted companies.
  1716. $q->clear();
  1717. $q->addTable('companies');
  1718. $q->addQuery('company_id, company_name, dep.*');
  1719. $q->addJoin('departments', 'dep', 'companies.company_id = dep.dept_company');
  1720. $q->addOrder('company_name,dept_parent,dept_name');
  1721. $q = $obj->setAllowedSQL($AppUI->user_id, $q);
  1722. $q = $dpt->setAllowedSQL($AppUI->user_id, $q);
  1723. $rows = $q->loadList();
  1724. //display the select list
  1725. $buffer = '<select name="department" id="department" onChange="document.pickCompany.submit()" class="text" style="width: 200px;">';
  1726. $company = '';
  1727. foreach ($company_array as $key => $c_name) {
  1728. $buffer .= '<option value="' . $company_prefix . $key . '" style="font-weight:bold;"' . ($company_id == $key ? 'selected="selected"' : '') . '>' . $c_name . '</option>' . "\n";
  1729. foreach ($rows as $row) {
  1730. if ($row['dept_parent'] == 0) {
  1731. if ($key == $row['company_id']) {
  1732. if ($row['dept_parent'] != null) {
  1733. findchilddept($rows, $row['dept_id']);
  1734. }
  1735. }
  1736. }
  1737. }
  1738. }
  1739. $buffer .= '</select>';
  1740. return $projects;
  1741. }
  1742. /**
  1743. * getProjectIndex() gets the key nr of a project record within an array of projects finding its primary key within the records so that you can call that array record to get the projects data
  1744. *
  1745. * @param mixed $arraylist array list of project elements to search
  1746. * @param mixed $project_id project id to search for
  1747. * @return int returns the array key of the project record in the array list or false if not found
  1748. */
  1749. // From: modules/projects/project.class.php
  1750. function getProjectIndex($arraylist, $project_id)
  1751. {
  1752. $result = false;
  1753. foreach ($arraylist as $key => $data) {
  1754. if ($data['project_id'] == $project_id) {
  1755. return $key;
  1756. }
  1757. }
  1758. return $result;
  1759. }
  1760. /**
  1761. * getDepartmentSelectionList() returns a tree of departments in <option> tags (originally used on the addedit interface to display the departments of a project)
  1762. *
  1763. * @param mixed $company_id the id of the company we are searching departments
  1764. * @param mixed $checked_array an array with the ids of the departments that should be selected on the list
  1765. * @param integer $dept_parent used when to determine the starting level on the tree, or by recursion
  1766. * @param integer $spaces used by recursion to add spaces to form the visual tree on the <select> element
  1767. * @return string returns the html <option> elements
  1768. */
  1769. // From: modules/projects/project.class.php
  1770. function getDepartmentSelectionList($company_id, $checked_array = array(), $dept_parent = 0, $spaces = 0)
  1771. {
  1772. global $departments_count, $AppUI;
  1773. $parsed = '';
  1774. if ($AppUI->isActiveModule('departments') && canView('departments')) {
  1775. $department = new CDepartment();
  1776. $depts_list = $department->departments($company_id, $dept_parent);
  1777. foreach ($depts_list as $dept_id => $dept_info) {
  1778. $selected = in_array($dept_id, $checked_array) ? ' selected="selected"' : '';
  1779. $parsed .= '<option value="' . $dept_id . '"' . $selected . '>' . str_repeat('&nbsp;', $spaces) . $dept_info['dept_name'] . '</option>';
  1780. $parsed .= getDepartmentSelectionList($company_id, $checked_array, $dept_id, $spaces + 5);
  1781. }
  1782. }
  1783. return $parsed;
  1784. }
  1785. // From: modules/reports/reports/allocateduserhours.php
  1786. function userUsageWeeks()
  1787. {
  1788. global $task_start_date, $task_end_date, $hours_added, $actual_date, $users, $user_data, $user_usage, $use_assigned_percentage, $user_tasks_counted_in, $task, $start_date, $end_date;
  1789. $task_duration_per_week = $task->getTaskDurationPerWeek($use_assigned_percentage);
  1790. $ted = new w2p_Utilities_Date(Date_Calc::endOfWeek($task_end_date->day, $task_end_date->month, $task_end_date->year));
  1791. $tsd = new w2p_Utilities_Date(Date_Calc::beginOfWeek($task_start_date->day, $task_start_date->month, $task_start_date->year));
  1792. $week_difference = $end_date->workingDaysInSpan($start_date) / count(explode(',', w2PgetConfig('cal_working_days')));
  1793. $actual_date = $start_date;
  1794. for ($i = 0; $i <= $week_difference; $i++) {
  1795. if (!$actual_date->before($tsd) && !$actual_date->after($ted)) {
  1796. $awoy = $actual_date->year . Date_Calc::weekOfYear($actual_date->day, $actual_date->month, $actual_date->year);
  1797. foreach ($users as $user_id => $user_data) {
  1798. if (!isset($user_usage[$user_id][$awoy])) {
  1799. $user_usage[$user_id][$awoy] = 0;
  1800. }
  1801. $percentage_assigned = $use_assigned_percentage ? ($user_data['perc_assignment'] / 100) : 1;
  1802. $hours_added = $task_duration_per_week * $percentage_assigned;
  1803. $user_usage[$user_id][$awoy] += $hours_added;
  1804. if ($user_usage[$user_id][$awoy] < 0.005) {
  1805. //We want to show at least 0.01 even when the assigned time is very small so we know
  1806. //that at that time the user has a running task
  1807. $user_usage[$user_id][$awoy] += 0.006;
  1808. $hours_added += 0.006;
  1809. }
  1810. // Let's register the tasks counted in for calculation
  1811. if (!array_key_exists($user_id, $user_tasks_counted_in)) {
  1812. $user_tasks_counted_in[$user_id] = array();
  1813. }
  1814. if (!array_key_exists($task->task_project, $user_tasks_counted_in[$user_id])) {
  1815. $user_tasks_counted_in[$user_id][$task->task_project] = array();
  1816. }
  1817. if (!array_key_exists($task->task_id, $user_tasks_counted_in[$user_id][$task->task_project])) {
  1818. $user_tasks_counted_in[$user_id][$task->task_project][$task->task_id] = 0;
  1819. }
  1820. // We add it up
  1821. $user_tasks_counted_in[$user_id][$task->task_project][$task->task_id] += $hours_added;
  1822. }
  1823. }
  1824. $actual_date->addSeconds(168 * 3600); // + one week
  1825. }
  1826. }
  1827. // From: modules/reports/reports/allocateduserhours.php
  1828. function showWeeks()
  1829. {
  1830. global $allocated_hours_sum, $end_date, $start_date, $AppUI, $user_list, $user_names, $user_usage, $table_header, $table_rows, $working_days_count, $total_hours_capacity, $total_hours_capacity_all;
  1831. $working_days_count = 0;
  1832. $allocated_hours_sum = 0;
  1833. $ed = new w2p_Utilities_Date(Date_Calc::endOfWeek($end_date->day, $end_date->month, $end_date->year));
  1834. $sd = new w2p_Utilities_Date(Date_Calc::beginOfWeek($start_date->day, $start_date->month, $start_date->year));
  1835. $week_difference = ceil($ed->workingDaysInSpan($sd) / count(explode(',', w2PgetConfig('cal_working_days'))));
  1836. $actual_date = $sd;
  1837. $table_header = '<tr><th>' . $AppUI->_('User') . '</th>';
  1838. for ($i = 0; $i < $week_difference; $i++) {
  1839. $actual_date->addSeconds(168 * 3600); // + one week
  1840. $working_days_count = $working_days_count + count(explode(',', w2PgetConfig('cal_working_days')));
  1841. }
  1842. $table_header .= '<th nowrap="nowrap" colspan="2">' . $AppUI->_('Allocated') . '</th></tr>';
  1843. $table_rows = '';
  1844. foreach ($user_list as $user_id => $user_data) {
  1845. $user_names[$user_id] = $user_data['contact_first_name'] . ' ' . $user_data['contact_last_name'];
  1846. if (isset($user_usage[$user_id])) {
  1847. $table_rows .= '<tr><td nowrap="nowrap">(' . $user_data['user_username'] . ') ' . $user_data['contact_first_name'] . ' ' . $user_data['contact_last_name'] . '</td>';
  1848. $array_sum = array_sum($user_usage[$user_id]);
  1849. $average_user_usage = number_format(($array_sum / ($week_difference * count(explode(',', w2PgetConfig('cal_working_days'))) * w2PgetConfig('daily_working_hours'))) * 100, 2);
  1850. $allocated_hours_sum += $array_sum;
  1851. $bar_color = 'blue';
  1852. if ($average_user_usage > 100) {
  1853. $bar_color = 'red';
  1854. $average_user_usage = 100;
  1855. }
  1856. $table_rows .= '<td ><div align="left">' . round($array_sum, 2) . ' ' . $AppUI->_('hours') . '</td> <td align="right"> ' . $average_user_usage;
  1857. $table_rows .= '%</div>';
  1858. $table_rows .= '<div align="left" style="height:2px;width:' . $average_user_usage . '%; background-color:' . $bar_color . '">&nbsp;</div></td>';
  1859. $table_rows .= '</tr>';
  1860. }
  1861. }
  1862. $total_hours_capacity = $working_days_count / 2 * w2PgetConfig('daily_working_hours') * count($user_usage);
  1863. $total_hours_capacity_all = $working_days_count / 2 * w2PgetConfig('daily_working_hours') * count($user_list);
  1864. }
  1865. // From: modules/reports/reports/allocateduserhours.php
  1866. function userUsageDays()
  1867. {
  1868. global $day_difference, $hours_added, $actual_date, $users, $user_data, $user_usage, $use_assigned_percentage, $user_tasks_counted_in, $task, $start_date, $end_date;
  1869. $task_duration_per_day = $task->getTaskDurationPerDay($use_assigned_percentage);
  1870. for ($i = 0; $i <= $day_difference; $i++) {
  1871. if (!$actual_date->before($start_date) && !$actual_date->after($end_date) && $actual_date->isWorkingDay()) {
  1872. foreach ($users as $user_id => $user_data) {
  1873. if (!isset($user_usage[$user_id][$actual_date->format('%Y%m%d')])) {
  1874. $user_usage[$user_id][$actual_date->format('%Y%m%d')] = 0;
  1875. }
  1876. $percentage_assigned = $use_assigned_percentage ? ($user_data['perc_assignment'] / 100) : 1;
  1877. $hours_added = $task_duration_per_day * $percentage_assigned;
  1878. $user_usage[$user_id][$actual_date->format('%Y%m%d')] += $hours_added;
  1879. if ($user_usage[$user_id][$actual_date->format('%Y%m%d')] < 0.005) {
  1880. //We want to show at least 0.01 even when the assigned time is very small so we know
  1881. //that at that time the user has a running task
  1882. $user_usage[$user_id][$actual_date->format('%Y%m%d')] += 0.006;
  1883. $hours_added += 0.006;
  1884. }
  1885. // Let's register the tasks counted in for calculation
  1886. if (!array_key_exists($user_id, $user_tasks_counted_in)) {
  1887. $user_tasks_counted_in[$user_id] = array();
  1888. }
  1889. if (!array_key_exists($task->task_project, $user_tasks_counted_in[$user_id])) {
  1890. $user_tasks_counted_in[$user_id][$task->task_project] = array();
  1891. }
  1892. if (!array_key_exists($task->task_id, $user_tasks_counted_in[$user_id][$task->task_project])) {
  1893. $user_tasks_counted_in[$user_id][$task->task_project][$task->task_id] = 0;
  1894. }
  1895. // We add it up
  1896. $user_tasks_counted_in[$user_id][$task->task_project][$task->task_id] += $hours_added;
  1897. }
  1898. }
  1899. $actual_date->addDays(1);
  1900. }
  1901. }
  1902. // From: modules/reports/reports/allocateduserhours.php
  1903. function showDays()
  1904. {
  1905. global $allocated_hours_sum, $end_date, $start_date, $AppUI, $user_list, $user_names, $user_usage, $hideNonWd, $table_header, $table_rows, $working_days_count, $total_hours_capacity, $total_hours_capacity_all;
  1906. $days_difference = $end_date->dateDiff($start_date);
  1907. $actual_date = $start_date;
  1908. $working_days_count = 0;
  1909. $allocated_hours_sum = 0;
  1910. $table_header = '<tr><th>' . $AppUI->_('User') . '</th>';
  1911. for ($i = 0; $i <= $days_difference; $i++) {
  1912. if ($actual_date->isWorkingDay()) {
  1913. $working_days_count++;
  1914. }
  1915. $actual_date->addDays(1);
  1916. }
  1917. $table_header .= '<th nowrap="nowrap" colspan="2">' . $AppUI->_('Allocated') . '</th></tr>';
  1918. $table_rows = '';
  1919. foreach ($user_list as $user_id => $user_data) {
  1920. $user_names[$user_id] = $user_data['contact_first_name'] . ' ' . $user_data['contact_last_name'];
  1921. if (isset($user_usage[$user_id])) {
  1922. $table_rows .= '<tr><td nowrap="nowrap">(' . $user_data['user_username'] . ') ' . $user_data['contact_first_name'] . ' ' . $user_data['contact_last_name'] . '</td>';
  1923. $array_sum = array_sum($user_usage[$user_id]);
  1924. $average_user_usage = number_format(($array_sum / ($working_days_count * w2PgetConfig('daily_working_hours'))) * 100, 2);
  1925. $allocated_hours_sum += $array_sum;
  1926. $bar_color = 'blue';
  1927. if ($average_user_usage > 100) {
  1928. $bar_color = 'red';
  1929. $average_user_usage = 100;
  1930. }
  1931. $table_rows .= '<td ><div align="left">' . round($array_sum, 2) . ' ' . $AppUI->_('hours') . '</td> <td align="right"> ' . $average_user_usage;
  1932. $table_rows .= '%</div>';
  1933. $table_rows .= '<div align="left" style="height:2px;width:' . $average_user_usage . '%; background-color:' . $bar_color . '">&nbsp;</div></td>';
  1934. $table_rows .= '</tr>';
  1935. }
  1936. }
  1937. $total_hours_capacity = $working_days_count * w2PgetConfig('daily_working_hours') * count($user_usage);
  1938. $total_hours_capacity_all = $working_days_count * w2PgetConfig('daily_working_hours') * count($user_list);
  1939. }
  1940. // From: modules/system/syskeys/index.php
  1941. function showRow($id = '', $key = 0, $title = '', $value = '')
  1942. {
  1943. global $canEdit, $sysval_id, $AppUI, $keys;
  1944. global $fixedSysVals;
  1945. $s = '';
  1946. if (($sysval_id == $title) && $canEdit) {
  1947. // edit form
  1948. $s .= '<tr><td><input type="hidden" name="sysval_id" value="' . $title . '" />&nbsp;</td>';
  1949. $s .= '<td valign="top"><a name="'.$title.'"> </a>' . arraySelect($keys, 'sysval_key_id', 'size="1" class="text"', $key) . '</td>';
  1950. $s .= '<td valign="top"><input type="text" name="sysval_title" value="' . w2PformSafe($title) . '" class="text" /></td>';
  1951. $s .= '<td valign="top"><textarea name="sysval_value" class="small" rows="5" cols="40">' . $value . '</textarea></td>';
  1952. $s .= '<td><input type="submit" value="' . $AppUI->_($id ? 'save' : 'add') . '" class="button btn btn-primary btn-mini" /></td><td>&nbsp;</td>';
  1953. } else {
  1954. $s = '<tr><td width="12" valign="top">';
  1955. if ($canEdit) {
  1956. $s .= '<a href="?m=system&u=syskeys&sysval_id=' . $title . '#'.$title.'" title="' . $AppUI->_('edit') . '">' . w2PshowImage('icons/stock_edit-16.png', 16, 16, '') . '</a></td>';
  1957. }
  1958. $s .= '<td valign="top">' . $keys[$key] . '</td>';
  1959. $s .= '<td valign="top">' . w2PformSafe($title) . '</td>';
  1960. $s .= '<td valign="top" colspan="2">' . $value . '</td>';
  1961. $s .= '<td valign="top" width="16">';
  1962. if ($canEdit && !in_array($title, $fixedSysVals)) {
  1963. $s .= '<a href="javascript:delIt(\'' . $title . '\')" title="' . $AppUI->_('delete') . '">' . w2PshowImage('icons/stock_delete-16.png', 16, 16, '') . '</a>';
  1964. }
  1965. $s .= '</td>';
  1966. }
  1967. $s .= '</tr>';
  1968. return $s;
  1969. }
  1970. // From: modules/system/syskeys/keys.php
  1971. function showRow_keys($id = 0, $name = '', $label = '')
  1972. {
  1973. global $canEdit, $syskey_id, $CR, $AppUI;
  1974. $s = '';
  1975. if ($syskey_id == $id && $canEdit) {
  1976. $s .= '<form name="sysKeyFrm" method="post" action="?m=system&u=syskeys&a=do_syskey_aed" accept-charset="utf-8">';
  1977. $s .= '<input type="hidden" name="del" value="0" />';
  1978. $s .= '<input type="hidden" name="syskey_id" value="' . $id . '" />';
  1979. $s .= '<tr>';
  1980. $s .= '<td>&nbsp;</td>';
  1981. $s .= '<td><input type="text" name="syskey_name" value="' . $name . '" class="text" /></td>';
  1982. $s .= '<td><textarea name="syskey_label" class="small" rows="2" cols="40">' . $label . '</textarea></td>';
  1983. $s .= '<td><input type="submit" value="' . $AppUI->_($id ? 'edit' : 'add') . '" class="button btn btn-primary btn-mini" /></td>';
  1984. $s .= '<td>&nbsp;</td>';
  1985. } else {
  1986. $s .= '<tr>';
  1987. $s .= '<td width="12">';
  1988. if ($canEdit) {
  1989. $s .= '<a href="?m=system&u=syskeys&a=keys&syskey_id=' . $id . '"><img src="' . w2PfindImage('icons/pencil.gif') . '" alt="edit" /></a>';
  1990. $s .= '</td>' . $CR;
  1991. }
  1992. $s .= '<td>' . $name . '</td>' . $CR;
  1993. $s .= '<td colspan="2">' . $label . '</td>' . $CR;
  1994. $s .= '<td width="16">';
  1995. if ($canEdit) {
  1996. $s .= '<a href="javascript:delIt(' . $id . ')"><img align="absmiddle" src="' . w2PfindImage('icons/trash.gif') . '" alt="' . $AppUI->_('delete') . '" /></a>';
  1997. }
  1998. $s .= '</td>' . $CR;
  1999. }
  2000. $s .= '</tr>' . $CR;
  2001. return $s;
  2002. }
  2003. ##
  2004. ## Returns the best color based on a background color (x is cross-over)
  2005. ##
  2006. function bestColor($bg, $lt = '#ffffff', $dk = '#000000')
  2007. {
  2008. // cross-over color = x
  2009. $x = 128;
  2010. $r = hexdec(substr($bg, 0, 2));
  2011. $g = hexdec(substr($bg, 2, 2));
  2012. $b = hexdec(substr($bg, 4, 2));
  2013. $y = 0.2126 * $r + 0.7152 * $g + 0.0722 * $b;
  2014. if ($y < $x) {
  2015. return $lt;
  2016. } else {
  2017. return $dk;
  2018. }
  2019. }
  2020. ##
  2021. ## returns a select box based on an key,value array where selected is based on key
  2022. ##
  2023. function arraySelect(&$arr, $select_name, $select_attribs, $selected, $translate = false)
  2024. {
  2025. global $AppUI;
  2026. if (!is_array($arr)) {
  2027. dprint(__file__, __line__, 0, 'arraySelect called with no array');
  2028. return '';
  2029. }
  2030. reset($arr);
  2031. $s = '<select id="' . $select_name . '" name="' . $select_name . '" ' . $select_attribs . '>';
  2032. // if we are dealing with multiple selected itens for multiple kind of listboxes
  2033. // we need to count them so that only those get selected.
  2034. if (is_array($selected)) {
  2035. $multiple = count($selected);
  2036. }
  2037. $did_selected = 0;
  2038. foreach ($arr as $k => $v) {
  2039. if ($translate) {
  2040. $v = $AppUI->_($v);
  2041. }
  2042. if (is_array($selected)) {
  2043. $s .= '<option value="' . $k . '"' . ((in_array($k, $selected) && !$did_selected) ? ' selected="selected"' : '') . '>' . $v . '</option>';
  2044. if (in_array($k, $selected)) {
  2045. // We found a match. Lets decrease the $multiples yet to be found
  2046. $multiple--;
  2047. }
  2048. if (!$multiple) {
  2049. // As soon as we found $multiple nr of matches we make sure no other gets selected by computer mistake by using the $did_selected lock
  2050. $did_selected = 1;
  2051. }
  2052. } else {
  2053. $s .= '<option value="' . $k . '"' . ((($k == $selected && strcmp($k, $selected) == 0) && !$did_selected) ? ' selected="selected"' : '') . '>' . $v . '</option>';
  2054. if (($k == $selected && strcmp($k, $selected) == 0)) {
  2055. // As soon as we find a match we make sure no other gets selected by computer mistake by using the $did_selected lock
  2056. $did_selected = 1;
  2057. }
  2058. }
  2059. }
  2060. $s .= '</select>';
  2061. return $s;
  2062. }
  2063. ##
  2064. ## returns a select box based on an key,value array where selected is based on key
  2065. ##
  2066. function arraySelectTree(&$arr, $select_name, $select_attribs, $selected, $translate = false)
  2067. {
  2068. reset($arr);
  2069. $children = array();
  2070. // first pass - collect children
  2071. foreach ($arr as $notUsed => $v) {
  2072. $pt = $v[2];
  2073. $list = isset($children[$pt]) ? $children[$pt] : array();
  2074. array_push($list, $v);
  2075. $children[$pt] = $list;
  2076. }
  2077. $list = tree_recurse($arr[0][2], '', array(), $children);
  2078. return arraySelect($list, $select_name, $select_attribs, $selected, $translate);
  2079. }
  2080. function tree_recurse($id, $indent, $list, $children)
  2081. {
  2082. if (isset($children[$id])) {
  2083. foreach ($children[$id] as $v) {
  2084. $id = $v[0];
  2085. $txt = $v[1];
  2086. $list[$id] = $indent . ' ' . $txt;
  2087. $list = tree_recurse($id, $indent . '--', $list, $children);
  2088. }
  2089. }
  2090. return $list;
  2091. }
  2092. /**
  2093. ** Provide Projects Selectbox sorted by Companies
  2094. ** @author gregorerhardt with special thanks to original author aramis
  2095. ** @param int userID
  2096. ** @param string HTML select box name identifier
  2097. ** @param string HTML attributes
  2098. ** @param int Proejct ID for preselection
  2099. ** @param int Project ID which will be excluded from the list
  2100. ** (e.g. in the tasks import list exclude the project to import into)
  2101. ** @return string HTML selectbox
  2102. */
  2103. function projectSelectWithOptGroup($user_id, $select_name, $select_attribs, $selected, $excludeProjWithId = null)
  2104. {
  2105. global $AppUI;
  2106. $q = new w2p_Database_Query();
  2107. $q->addTable('projects', 'pr');
  2108. $q->addQuery('DISTINCT pr.project_id, co.company_name, project_name');
  2109. $q->addJoin('companies', 'co', 'co.company_id = pr.project_company');
  2110. if (!empty($excludeProjWithId)) {
  2111. $q->addWhere('pr.project_id <> ' . $excludeProjWithId);
  2112. }
  2113. $proj = new CProject();
  2114. $q = $proj->setAllowedSQL($user_id, $q, null, 'pr');
  2115. $q->addOrder('co.company_name, project_name');
  2116. $projects = $q->loadList();
  2117. $s = '<select name="' . $select_name . '" ' . $select_attribs . '>';
  2118. $s .= '<option value="0" ' . ($selected == 0 ? 'selected="selected"' : '') . ' >' . $AppUI->_('None') . '</option>';
  2119. $current_company = '';
  2120. foreach ($projects as $p) {
  2121. if ($p['company_name'] != $current_company) {
  2122. $current_company = $p['company_name'];
  2123. $s .= '<optgroup label="' . $current_company . '" >' . $current_company . '</optgroup>';
  2124. }
  2125. $s .= '<option value="' . $p['project_id'] . '" ' . ($selected == $p['project_id'] ? 'selected="selected"' : '') . '>&nbsp;&nbsp;&nbsp;' . $p['project_name'] . '</option>';
  2126. }
  2127. $s .= '</select>';
  2128. return $s;
  2129. }
  2130. ##
  2131. ## breadCrumbs - show a separated list of crumbs
  2132. ## array is in the form url => title
  2133. ##
  2134. function breadCrumbs(&$arr)
  2135. {
  2136. global $AppUI;
  2137. $crumbs = array();
  2138. foreach ($arr as $k => $v) {
  2139. $crumbs[] = '<a class="button" href="' . $k . '"><span>' . $AppUI->_($v) . '</span></a>';
  2140. }
  2141. return implode('</td><td align="left" nowrap="nowrap">', $crumbs);
  2142. }
  2143. function w2PgetUsers()
  2144. {
  2145. global $AppUI;
  2146. $q = new w2p_Database_Query;
  2147. $q->addTable('users');
  2148. $q->addQuery('user_id, concat_ws(\' \', contact_first_name, contact_last_name) as name');
  2149. $q->addJoin('contacts', 'con', 'con.contact_id = user_contact', 'inner');
  2150. $q->addOrder('contact_first_name,contact_last_name');
  2151. $obj = new CCompany();
  2152. $companies = $obj->getAllowedSQL($AppUI->user_id, 'company_id');
  2153. $q->addJoin('companies', 'com', 'company_id = contact_company');
  2154. if ($companies) {
  2155. $q->addWhere('(' . implode(' OR ', $companies) . ' OR contact_company=\'\' OR contact_company IS NULL OR contact_company = 0)');
  2156. }
  2157. if ($AppUI->isActiveModule('departments')) {
  2158. $dpt = new CDepartment();
  2159. $depts = $dpt->getAllowedSQL($AppUI->user_id, 'dept_id');
  2160. $q->addJoin('departments', 'dep', 'dept_id = contact_department');
  2161. if ($depts) {
  2162. $q->addWhere('(' . implode(' OR ', $depts) . ' OR contact_department=0)');
  2163. }
  2164. }
  2165. return $q->loadHashList();
  2166. }
  2167. function getUsers($stub = null, $where = null, $orderby = 'contact_first_name, contact_last_name')
  2168. {
  2169. global $AppUI;
  2170. $q = new w2p_Database_Query;
  2171. $q->addTable('users');
  2172. $q->addQuery('DISTINCT(user_id), user_username, contact_last_name, contact_first_name,
  2173. company_name, contact_company, dept_id, dept_name, contact_display_name,
  2174. contact_display_name as contact_name, contact_email, user_type');
  2175. $q->addJoin('contacts', 'con', 'con.contact_id = user_contact', 'inner');
  2176. if ($stub) {
  2177. $q->addWhere('(UPPER(user_username) LIKE \'' . $stub . '%\' or UPPER(contact_first_name) LIKE \'' . $stub . '%\' OR UPPER(contact_last_name) LIKE \'' . $stub . '%\')');
  2178. } elseif ($where) {
  2179. $where = $q->quote('%' . $where . '%');
  2180. $q->addWhere('(UPPER(user_username) LIKE ' . $where . ' OR UPPER(contact_first_name) LIKE ' . $where . ' OR UPPER(contact_last_name) LIKE ' . $where . ')');
  2181. }
  2182. $q->addGroup('user_id');
  2183. $q->addOrder($orderby);
  2184. // get CCompany() to filter by company
  2185. $obj = new CCompany();
  2186. $companies = $obj->getAllowedSQL($AppUI->user_id, 'company_id');
  2187. $q->addJoin('companies', 'com', 'company_id = contact_company');
  2188. if ($companies) {
  2189. $q->addWhere('(' . implode(' OR ', $companies) . ' OR contact_company=\'\' OR contact_company IS NULL OR contact_company = 0)');
  2190. }
  2191. $dpt = new CDepartment();
  2192. $depts = $dpt->getAllowedSQL($AppUI->user_id, 'dept_id');
  2193. $q->addJoin('departments', 'dep', 'dept_id = contact_department');
  2194. if ($depts) {
  2195. $q->addWhere('(' . implode(' OR ', $depts) . ' OR contact_department=0)');
  2196. }
  2197. return $q;
  2198. }
  2199. function w2PgetUsersList($stub = null, $where = null, $orderby = 'contact_first_name, contact_last_name')
  2200. {
  2201. $q = getUsers($stub, $where, $orderby);
  2202. return $q->loadList();
  2203. }
  2204. function w2PgetUsersHashList($stub = null, $where = null, $orderby = 'contact_first_name, contact_last_name')
  2205. {
  2206. $q = getUsers($stub, $where, $orderby);
  2207. return $q->loadHashList('user_id');
  2208. }
  2209. ##
  2210. ## displays the configuration array of a module for informational purposes
  2211. ##
  2212. function w2PshowModuleConfig($config)
  2213. {
  2214. global $AppUI;
  2215. $s = '<table cellspacing="2" cellpadding="2" border="0" class="std" width="50%">';
  2216. $s .= '<tr><th colspan="2">' . $AppUI->_('Module Configuration') . '</th></tr>';
  2217. foreach ($config as $k => $v) {
  2218. $s .= '<tr><td width="50%">' . $AppUI->_($k) . '</td><td width="50%" class="hilite">' . $AppUI->_($v) . '</td></tr>';
  2219. }
  2220. $s .= '</table>';
  2221. return ($s);
  2222. }
  2223. /**
  2224. * Function to recussively find an image in a number of places
  2225. * @param string The name of the image
  2226. * @param string Optional name of the current module
  2227. */
  2228. function w2PfindImage($name, $module = null)
  2229. {
  2230. // uistyle must be declared globally
  2231. global $uistyle;
  2232. if ($module && file_exists(W2P_BASE_DIR . '/modules/' . $module . '/images/' . $name)) {
  2233. return './modules/' . $module . '/images/' . $name;
  2234. } elseif ($module && file_exists(W2P_BASE_DIR . '/style/' . $uistyle . '/images/modules/' . $module . '/' . $name)) {
  2235. return './style/' . $uistyle . '/images/modules/' . $module . '/' . $name;
  2236. } elseif (file_exists(W2P_BASE_DIR . '/style/' . $uistyle . '/images/icons/' . $name)) {
  2237. return './style/' . $uistyle . '/images/icons/' . $name;
  2238. } elseif (file_exists(W2P_BASE_DIR . '/style/' . $uistyle . '/images/obj/' . $name)) {
  2239. return './style/' . $uistyle . '/images/obj/' . $name;
  2240. } elseif (file_exists(W2P_BASE_DIR . '/style/' . $uistyle . '/images/' . $name)) {
  2241. return './style/' . $uistyle . '/images/' . $name;
  2242. } elseif ($module && file_exists(W2P_BASE_DIR . '/style/' . w2PgetConfig('host_style') . '/images/modules/' . $module . '/' . $name)) {
  2243. return './style/' . w2PgetConfig('host_style') . '/images/modules/' . $module . '/' . $name;
  2244. } elseif (file_exists(W2P_BASE_DIR . '/style/' . w2PgetConfig('host_style') . '/images/icons/' . $name)) {
  2245. return './style/' . w2PgetConfig('host_style') . '/images/icons/' . $name;
  2246. } elseif (file_exists(W2P_BASE_DIR . '/style/' . w2PgetConfig('host_style') . '/images/obj/' . $name)) {
  2247. return './style/' . w2PgetConfig('host_style') . '/images/obj/' . $name;
  2248. } elseif (file_exists(W2P_BASE_DIR . '/style/web2project/images/obj/' . $name)) {
  2249. return './style/web2project/images/obj/' . $name;
  2250. } else {
  2251. return './style/web2project/images/' . $name;
  2252. }
  2253. }
  2254. /**
  2255. * Workaround removed due to problems in Opera and other issues
  2256. * with IE6.
  2257. * Workaround to display png images with alpha-transparency in IE6.0
  2258. * @param string The name of the image
  2259. * @param string The image width
  2260. * @param string The image height
  2261. * @param string The alt text for the image
  2262. */
  2263. function w2PshowImage($src, $notUsed = '', $notUsed2 = '', $alt = '', $title = '', $module = null)
  2264. {
  2265. global $m;
  2266. if ($src == '') {
  2267. return '';
  2268. } elseif ($module) {
  2269. $src = w2PfindImage($src, $module);
  2270. } else {
  2271. $src = w2PfindImage($src, $m);
  2272. }
  2273. if (!$alt && !$title) {
  2274. $result = '';
  2275. } elseif ($alt && $title) {
  2276. $result = w2PtoolTip($alt, $title);
  2277. } elseif ($alt && !$title) {
  2278. $result = w2PtoolTip($m, $alt);
  2279. } elseif (!$alt && $title) {
  2280. $result = w2PtoolTip($m, $title);
  2281. }
  2282. $result .= '<img src="' . $src . '" alt="' . $alt . '" />';
  2283. if ($alt || $title) {
  2284. $result .= w2PendTip();
  2285. }
  2286. return $result;
  2287. }
  2288. // ****************************************************************************
  2289. // Page numbering variables
  2290. // Pablo Roca (pabloroca@Xmvps.org) (Remove the X)
  2291. // 19 August 2003
  2292. //
  2293. // $tab - file category
  2294. // $page - actual page to show
  2295. // $xpg_pagesize - max rows per page
  2296. // $xpg_min - initial record in the SELECT LIMIT
  2297. // $xpg_totalrecs - total rows selected
  2298. // $xpg_sqlrecs - total rows from SELECT LIMIT
  2299. // $xpg_total_pages - total pages
  2300. // $xpg_next_page - next pagenumber
  2301. // $xpg_prev_page - previous pagenumber
  2302. // $xpg_break - stop showing page numbered list?
  2303. // $xpg_sqlcount - SELECT for the COUNT total
  2304. // $xpg_sqlquery - SELECT for the SELECT LIMIT
  2305. // $xpg_result - pointer to results from SELECT LIMIT
  2306. function buildPaginationNav($AppUI, $m, $tab, $xpg_totalrecs, $xpg_pagesize, $page)
  2307. {
  2308. $xpg_total_pages = ($xpg_totalrecs > $xpg_pagesize) ? ceil($xpg_totalrecs / $xpg_pagesize) : 0;
  2309. $xpg_break = false;
  2310. $s = '<table width="100%" cellspacing="0" cellpadding="0" border="0"><tr>';
  2311. if ($xpg_totalrecs > $xpg_pagesize) {
  2312. $xpg_prev_page = $page - 1;
  2313. $xpg_next_page = $page + 1;
  2314. // left buttoms
  2315. if ($xpg_prev_page > 0) {
  2316. $s .= '<td align="left" width="15%"><a href="./index.php?m=' . $m . '&amp;tab=' . $tab . '&amp;page=1"><img src="' . w2PfindImage('navfirst.gif') . '" alt="First Page"></a>&nbsp;&nbsp;';
  2317. $s .= '<a href="./index.php?m=' . $m . '&amp;tab=' . $tab . '&amp;page=' . $xpg_prev_page . '"><img src="' . w2PfindImage('navleft.gif') . '" alt="Previous page (' . $xpg_prev_page . ')"></a></td>';
  2318. } else {
  2319. $s .= '<td width="15%">&nbsp;</td>';
  2320. }
  2321. // central text (files, total pages, ...)
  2322. $s .= '<td align="center" width="70%">';
  2323. $s .= $xpg_totalrecs . ' ' . $AppUI->_('Record(s)') . ' ' . $xpg_total_pages . ' ' . $AppUI->_('Page(s)');
  2324. // Page numbered list, up to 30 pages
  2325. $s .= ' [ ';
  2326. for ($n = $page > 16 ? $page - 16 : 1; $n <= $xpg_total_pages; $n++) {
  2327. if ($n == $page) {
  2328. $s .= '<b>' . $n . '</b></a>';
  2329. } else {
  2330. $s .= '<a href="./index.php?m=' . $m . '&amp;tab=' . $tab . '&amp;page=' . $n . '">' . $n . '</a>';
  2331. }
  2332. if ($n >= 30 + $page - 15) {
  2333. $xpg_break = true;
  2334. break;
  2335. } elseif ($n < $xpg_total_pages) {
  2336. $s .= ' | ';
  2337. }
  2338. }
  2339. if (!isset($xpg_break)) { // are we supposed to break ?
  2340. if ($n == $page) {
  2341. $s .= '<' . $n . '</a>';
  2342. } else {
  2343. $s .= '<a href="./index.php?m=' . $m . '&amp;tab=' . $tab . '&amp;page=' . $xpg_total_pages . '">' . $n . '</a>';
  2344. }
  2345. }
  2346. $s .= ' ] ';
  2347. $s .= '</td>';
  2348. // right buttoms
  2349. if ($xpg_next_page <= $xpg_total_pages) {
  2350. $s .= '<td align="right" width="15%"><a href="./index.php?m=' . $m . '&amp;tab=' . $tab . '&amp;page=' . $xpg_next_page . '"><img src="' . w2PfindImage('navright.gif') . '" alt="Next Page (' . $xpg_next_page . ')"></a>&nbsp;&nbsp;';
  2351. $s .= '<a href="./index.php?m=' . $m . '&amp;tab=' . $tab . '&amp;page=' . $xpg_total_pages . '"><img src="' . w2PfindImage('navlast.gif') . '" alt="Last Page"></a></td>';
  2352. } else {
  2353. $s .= '<td width="15%">&nbsp;</td></tr>';
  2354. }
  2355. }
  2356. $s .= '</table>';
  2357. return $s;
  2358. }
  2359. /**
  2360. * function to return a default value if a variable is not set
  2361. */
  2362. function defVal($var, $def)
  2363. {
  2364. return isset($var) ? $var : $def;
  2365. }
  2366. function addHistory($table, $id, $action = 'modify', $description = '', $project_id = 0)
  2367. {
  2368. global $AppUI;
  2369. /*
  2370. * TODO:
  2371. * 1) description should be something like:
  2372. * command(arg1, arg2...)
  2373. * The command should be as module_action
  2374. * for example:
  2375. * forums_new('Forum Name', 'URL')
  2376. *
  2377. * This way, the history module will be able to display descriptions
  2378. * using locale definitions:
  2379. * "forums_new" -> "New forum '%s' was created" -> "Se ha creado un nuevo foro llamado '%s'"
  2380. *
  2381. * 2) project_id and module_id should be provided in order to filter history entries
  2382. *
  2383. */
  2384. if (!$AppUI->isActiveModule('history')) {
  2385. return;
  2386. }
  2387. if (is_null($action)) {
  2388. $action = 'delete';
  2389. }
  2390. $q = new w2p_Database_Query;
  2391. $q->addTable('history');
  2392. $q->addInsert('history_action', $action);
  2393. $q->addInsert('history_item', (int) $id);
  2394. $q->addInsert('history_description', $description);
  2395. $q->addInsert('history_user', (int) $AppUI->user_id);
  2396. $q->addInsert('history_date', "'".$q->dbfnNowWithTZ()."'", false, true);
  2397. $q->addInsert('history_project', (int) $project_id);
  2398. $q->addInsert('history_table', $table);
  2399. $q->exec();
  2400. //echo db_error();
  2401. }
  2402. function w2PgetSysVal($title)
  2403. {
  2404. $q = new w2p_Database_Query;
  2405. $q->addTable('sysvals');
  2406. $q->addQuery('sysval_value_id, sysval_value');
  2407. $q->addWhere("sysval_title = '$title'");
  2408. $q->addOrder('sysval_value_id ASC');
  2409. $rows = $q->loadList();
  2410. $arr = array();
  2411. // We use trim() to make sure a numeric that has spaces
  2412. // is properly treated as a numeric
  2413. $key_sort = SORT_NUMERIC;
  2414. foreach ($rows as $notUsed => $item) {
  2415. if ($item) {
  2416. $arr[trim($item['sysval_value_id'])] = trim($item['sysval_value']);
  2417. if (!is_numeric(trim($item['sysval_value_id']))) {
  2418. $key_sort = SORT_REGULAR;
  2419. }
  2420. }
  2421. }
  2422. ksort($arr, $key_sort);
  2423. return $arr;
  2424. }
  2425. function w2PuserHasRole($name)
  2426. {
  2427. global $AppUI;
  2428. $uid = $AppUI->user_id;
  2429. $q = new w2p_Database_Query;
  2430. $q->addTable('roles', 'r');
  2431. $q->addTable('user_roles', 'ur');
  2432. $q->addQuery('r.role_id');
  2433. $q->addWhere('ur.user_id = ' . $uid . ' AND ur.role_id = r.role_id AND r.role_name = \'' . $name . '\'');
  2434. return $q->loadResult();
  2435. }
  2436. function w2PformatDuration($x)
  2437. {
  2438. global $AppUI;
  2439. $dur_day = floor($x / w2PgetConfig('daily_working_hours'));
  2440. $dur_hour = $x - $dur_day * w2PgetConfig('daily_working_hours');
  2441. $str = '';
  2442. if ($dur_day > 1) {
  2443. $str .= $dur_day . ' ' . $AppUI->_('days') . ' ';
  2444. } elseif ($dur_day == 1) {
  2445. $str .= $dur_day . ' ' . $AppUI->_('day') . ' ';
  2446. }
  2447. if ($dur_hour > 1) {
  2448. $str .= $dur_hour . ' ' . $AppUI->_('hours');
  2449. } elseif ($dur_hour > 0 and $dur_hour <= 1) {
  2450. $str .= $dur_hour . ' ' . $AppUI->_('hour');
  2451. }
  2452. if ($str == '') {
  2453. $str = $AppUI->_('n/a');
  2454. }
  2455. return $str;
  2456. }
  2457. /**
  2458. */
  2459. function w2PsetMicroTime()
  2460. {
  2461. global $microTimeSet;
  2462. list($usec, $sec) = explode(' ', microtime());
  2463. $microTimeSet = (float) $usec + (float) $sec;
  2464. }
  2465. function w2PsetExecutionConditions()
  2466. {
  2467. $memoryLimt = (w2PgetConfig('reset_memory_limit') != '') ? w2PgetConfig('reset_memory_limit') : '64M';
  2468. ini_set('max_execution_time', 180);
  2469. ini_set('memory_limit', $memoryLimt);
  2470. }
  2471. /**
  2472. */
  2473. function w2PgetMicroDiff()
  2474. {
  2475. global $microTimeSet;
  2476. $mt = $microTimeSet;
  2477. w2PsetMicroTime();
  2478. return sprintf('%.3f', $microTimeSet - $mt);
  2479. }
  2480. /**
  2481. * Make text safe to output into double-quote enclosed attirbutes of an HTML tag
  2482. */
  2483. function w2PformSafe($txt, $deslash = false)
  2484. {
  2485. global $locale_char_set;
  2486. if (!$locale_char_set) {
  2487. $locale_char_set = 'utf-8';
  2488. }
  2489. if (is_object($txt)) {
  2490. foreach (get_object_vars($txt) as $k => $v) {
  2491. if ($deslash) {
  2492. $obj->$k = htmlspecialchars(stripslashes($v), ENT_COMPAT, $locale_char_set);
  2493. } else {
  2494. $obj->$k = htmlspecialchars($v, ENT_COMPAT, $locale_char_set);
  2495. }
  2496. }
  2497. } elseif (is_array($txt)) {
  2498. foreach ($txt as $k => $v) {
  2499. if ($deslash) {
  2500. $txt[$k] = htmlspecialchars(stripslashes($v), ENT_COMPAT, $locale_char_set);
  2501. } else {
  2502. $txt[$k] = htmlspecialchars($v, ENT_COMPAT, $locale_char_set);
  2503. }
  2504. }
  2505. } else {
  2506. if ($deslash) {
  2507. $txt = htmlspecialchars(stripslashes($txt), ENT_COMPAT, $locale_char_set);
  2508. } else {
  2509. $txt = htmlspecialchars($txt, ENT_COMPAT, $locale_char_set);
  2510. }
  2511. }
  2512. return $txt;
  2513. }
  2514. function formatTime($uts)
  2515. {
  2516. global $AppUI;
  2517. $date = new w2p_Utilities_Date();
  2518. $date->setDate($uts, DATE_FORMAT_UNIXTIME);
  2519. return $date->format($AppUI->getPref('SHDATEFORMAT'));
  2520. }
  2521. function file_size($size)
  2522. {
  2523. $size = (int) $size;
  2524. if ($size > 1024 * 1024 * 1024)
  2525. return round($size / 1024 / 1024 / 1024, 2) . ' Gb';
  2526. if ($size > 1024 * 1024)
  2527. return round($size / 1024 / 1024, 2) . ' Mb';
  2528. if ($size > 1024)
  2529. return round($size / 1024, 2) . ' Kb';
  2530. return $size . ' B';
  2531. }
  2532. /**
  2533. * This function is necessary because Windows likes to
  2534. * write their own standards. Nothing that depends on locales
  2535. * can be trusted in Windows.
  2536. */
  2537. function formatCurrency($number, $format)
  2538. {
  2539. global $AppUI, $locale_char_set;
  2540. if (!$format) {
  2541. $format = $AppUI->getPref('CURRENCYFORM');
  2542. }
  2543. // If the requested locale doesn't work, don't fail,
  2544. // revert to the system default.
  2545. if ($locale_char_set != 'utf-8' || !setlocale(LC_MONETARY, $format . '.UTF8')) {
  2546. if (!setlocale(LC_MONETARY, $format)) {
  2547. setlocale(LC_MONETARY, '');
  2548. }
  2549. }
  2550. // Even money_format can't be trusted in Windows. It simply does not work on systems that don't have strfmon capabilities. Use number_format as fallback.
  2551. return function_exists('money_format') ? money_format('%i', $number) : number_format($number, 2);
  2552. }
  2553. function format_backtrace($bt, $file, $line, $msg)
  2554. {
  2555. trigger_error('ERROR: ' . $file . '(' . $line . ') : ' . $msg, E_USER_WARNING);
  2556. trigger_error('Backtrace:', E_USER_WARNING);
  2557. foreach ($bt as $level => $frame) {
  2558. trigger_error($level . ' ' . $frame['file'] . ':' . $frame['line'] . ' ' . $frame['function'] . "()", E_USER_WARNING);
  2559. }
  2560. }
  2561. function dprint($file, $line, $level, $msg)
  2562. {
  2563. $max_level = (int) w2PgetConfig('debug');
  2564. $display_debug = w2PgetConfig('display_debug', false);
  2565. if ($level <= $max_level) {
  2566. error_log($file . '(' . $line . '): ' . $msg);
  2567. if ($display_debug) {
  2568. echo $file . '(' . $line . '): ' . $msg . ' <br />';
  2569. }
  2570. if ($level == 0 && $max_level > 0) {
  2571. format_backtrace(debug_backtrace(), $file, $line, $msg);
  2572. }
  2573. }
  2574. }
  2575. /**
  2576. * Return a list of modules that are associated with tabs for this
  2577. * page. This can be used to find post handlers, for instance.
  2578. */
  2579. function findTabModules($module, $file = null)
  2580. {
  2581. $modlist = array();
  2582. if (!isset($_SESSION['all_tabs']) || !isset($_SESSION['all_tabs'][$module])) {
  2583. return $modlist;
  2584. }
  2585. if (isset($file)) {
  2586. if (isset($_SESSION['all_tabs'][$module][$file]) && is_array($_SESSION['all_tabs'][$module][$file])) {
  2587. $tabs_array = &$_SESSION['all_tabs'][$module][$file];
  2588. } else {
  2589. return $modlist;
  2590. }
  2591. } else {
  2592. $tabs_array = &$_SESSION['all_tabs'][$module];
  2593. }
  2594. foreach ($tabs_array as $tab) {
  2595. if (isset($tab['module'])) {
  2596. $modlist[] = $tab['module'];
  2597. }
  2598. }
  2599. return array_unique($modlist);
  2600. }
  2601. /**
  2602. * Return a list of modules that are associated with crumbs for this
  2603. * page. This can be used to find post handlers, for instance.
  2604. */
  2605. function findCrumbModules($module, $file = null)
  2606. {
  2607. $modlist = array();
  2608. if (!isset($_SESSION['all_crumbs']) || !isset($_SESSION['all_crumbs'][$module])) {
  2609. return $modlist;
  2610. }
  2611. if (isset($file)) {
  2612. if (isset($_SESSION['all_crumbs'][$module][$file]) && is_array($_SESSION['all_crumbs'][$module][$file])) {
  2613. $crumbs_array = &$_SESSION['all_crumbs'][$module][$file];
  2614. } else {
  2615. return $modlist;
  2616. }
  2617. } else {
  2618. $crumbs_array = &$_SESSION['all_crumbs'][$module];
  2619. }
  2620. foreach ($crumbs_array as $crumb) {
  2621. if (isset($crumb['module'])) {
  2622. $modlist[] = $crumb['module'];
  2623. }
  2624. }
  2625. return array_unique($modlist);
  2626. }
  2627. function getUsersArray()
  2628. {
  2629. return w2PgetUsersHashList();
  2630. }
  2631. function getUsersCombo($default_user_id = 0, $first_option = 'All users')
  2632. {
  2633. global $AppUI;
  2634. $parsed = '<select name="user_id" class="text">';
  2635. if ($first_option != '') {
  2636. $parsed .= '<option value="0" ' . (!$default_user_id ? 'selected="selected"' : '') . '>' . $AppUI->_($first_option) . '</option>';
  2637. }
  2638. foreach (getUsersArray() as $user_id => $user) {
  2639. $selected = $user_id == $default_user_id ? ' selected="selected"' : '';
  2640. $parsed .= '<option value="' . $user_id . '"' . $selected . '>' . $user['contact_first_name'] . ' ' . $user['contact_last_name'] . '</option>';
  2641. }
  2642. $parsed .= '</select>';
  2643. return $parsed;
  2644. }
  2645. /**
  2646. * Function to format hours into useful numbers.
  2647. * Supplied by GrahamJB.
  2648. */
  2649. function formatHours($hours)
  2650. {
  2651. global $AppUI;
  2652. $hours = (int) $hours;
  2653. $working_hours = w2PgetConfig('daily_working_hours');
  2654. if ($hours < $working_hours) {
  2655. if ($hours == 1) {
  2656. return '1 ' . $AppUI->_('hour');
  2657. } else {
  2658. return $hours . ' ' . $AppUI->_('hours');
  2659. }
  2660. }
  2661. $hoursPart = $hours % $working_hours;
  2662. $daysPart = (int) ($hours / $working_hours);
  2663. if ($hoursPart == 0) {
  2664. if ($daysPart == 1) {
  2665. return '1 ' . $AppUI->_('day');
  2666. } else {
  2667. return $daysPart . ' ' . $AppUI->_('days');
  2668. }
  2669. }
  2670. if ($daysPart == 1) {
  2671. return '1 ' . $AppUI->_('day') . ' ' . $hoursPart . ' ' . $AppUI->_('hr');
  2672. } else {
  2673. return $daysPart . ' ' . $AppUI->_('days') . ' ' . $hoursPart . ' ' . $AppUI->_('hr');
  2674. }
  2675. }
  2676. /*
  2677. ** Create the Required Fields (From Sysvals) JavaScript Code
  2678. ** For instance implemented in projects and tasks addedit.php
  2679. ** @param array required field array from SysVals
  2680. */
  2681. function w2PrequiredFields($requiredFields)
  2682. {
  2683. global $AppUI;
  2684. $buffer = 'var foc=false;';
  2685. if (!empty($requiredFields)) {
  2686. foreach ($requiredFields as $rf => $comparator) {
  2687. $buffer .= 'if (' . $rf . html_entity_decode($comparator, ENT_QUOTES) . ') {';
  2688. $buffer .= 'msg += "\n' . $AppUI->_('required_field_' . $rf, UI_OUTPUT_JS) . '";';
  2689. /* MSIE cannot handle the focus command for some disabled or hidden fields like the start/end date fields
  2690. ** Another workaround would be to check whether the field is disabled,
  2691. ** but then one would for instance need to use end_date instead of project_end_date in the projects addedit site.
  2692. ** As this cannot be guaranteed since these fields are grabbed from a user-specifiable
  2693. ** System Value it's IMHO more safe to disable the focus for MSIE.
  2694. */
  2695. $r = strstr($rf, '.');
  2696. $buffer .= 'if ((foc==false) && (navigator.userAgent.indexOf(\'MSIE\')== -1)) {';
  2697. $buffer .= 'f.' . substr($r, 1, strpos($r, '.', 1) - 1) . '.focus();';
  2698. $buffer .= 'foc=true;}}';
  2699. }
  2700. }
  2701. return $buffer;
  2702. }
  2703. /**
  2704. * Return the number of bytes represented by a PHP.INI value
  2705. */
  2706. function w2PgetBytes($str)
  2707. {
  2708. $val = $str;
  2709. if (preg_match('/^([0-9]+)([kmg])?$/i', $str, $match)) {
  2710. if (!empty($match[2])) {
  2711. switch (strtolower($match[2])) {
  2712. case 'k':
  2713. $val = $match[1] * 1024;
  2714. break;
  2715. case 'm':
  2716. $val = $match[1] * 1024 * 1024;
  2717. break;
  2718. case 'g':
  2719. $val = $match[1] * 1024 * 1024 * 1024;
  2720. break;
  2721. }
  2722. }
  2723. }
  2724. return $val;
  2725. }
  2726. /**
  2727. * Check for a memory limit, if we can't generate it then we fail.
  2728. * @param int $min minimum amount of memory needed
  2729. * @param bool $revert revert back to original config after test.
  2730. * @return bool true if we have the minimum amount of RAM and if we can modify RAM
  2731. */
  2732. function w2PcheckMem($min = 0, $revert = false)
  2733. {
  2734. // First of all check if we have the minimum memory requirement.
  2735. $want = w2PgetBytes(w2PgetConfig('reset_memory_limit'));
  2736. $have = ini_get('memory_limit');
  2737. // Try upping the memory limit based on our config
  2738. ini_set('memory_limit', w2PgetConfig('reset_memory_limit'));
  2739. $now = w2PgetBytes(ini_get('memory_limit'));
  2740. // Revert, if necessary, back to the original after testing.
  2741. if ($revert) {
  2742. ini_set('memory_limit', $have);
  2743. }
  2744. if ($now < $want || $now < $min) {
  2745. return false;
  2746. } else {
  2747. return true;
  2748. }
  2749. }
  2750. /**
  2751. * decode HTML entities
  2752. */
  2753. function w2PHTMLDecode($txt)
  2754. {
  2755. global $locale_char_set;
  2756. if (!$locale_char_set) {
  2757. $locale_char_set = 'utf-8';
  2758. }
  2759. if (is_object($txt)) {
  2760. foreach (get_object_vars($txt) as $k => $v) {
  2761. $txt->$k = html_entity_decode($v, ENT_COMPAT);
  2762. }
  2763. } else {
  2764. if (is_array($txt)) {
  2765. foreach ($txt as $k => $v) {
  2766. $txt[$k] = (is_array($v)) ? $v : html_entity_decode($v, ENT_COMPAT);
  2767. }
  2768. } else {
  2769. $txt = html_entity_decode($txt, ENT_COMPAT);
  2770. }
  2771. }
  2772. return $txt;
  2773. }
  2774. function w2PtoolTip($header = '', $tip = '', $raw = false, $id = '')
  2775. {
  2776. global $AppUI;
  2777. $id = ('' == $id) ? '' : 'id="' . $id . '"';
  2778. if ($raw) {
  2779. $starttip = '<span ' . $id . ' title="&lt;h4&gt;' . nl2br($AppUI->_($header)) . '&lt;/h4&gt; ' . nl2br($AppUI->_($tip)) . '">';
  2780. } else {
  2781. $starttip = '<span ' . $id . ' title="&lt;h4&gt;' . nl2br(ucwords(strtolower($AppUI->_($header)))) . '&lt;/h4&gt; ' . nl2br(strtolower($AppUI->_($tip))) . '">';
  2782. }
  2783. return $starttip;
  2784. }
  2785. function w2PendTip()
  2786. {
  2787. $endtip = '</span>';
  2788. return $endtip;
  2789. }
  2790. /**
  2791. * Write debugging to debug.log file
  2792. *
  2793. * @param string $s the debug message
  2794. * @param string $t the header of the message
  2795. * @param string $f the script filename
  2796. * @param string $l the script line
  2797. * @access public
  2798. */
  2799. function w2PwriteDebug($s, $t = '', $f = '?', $l = '?')
  2800. {
  2801. global $debug;
  2802. $debug_file = W2P_BASE_DIR . '/files/debug.log';
  2803. if ($debug && ($fp = fopen($debug_file, "at"))) {
  2804. fputs($fp, "Debug message from file [$f], line [$l], at: " . strftime('%H:%S'));
  2805. if ($t) {
  2806. fputs($fp, "\n * * $t * *\n");
  2807. }
  2808. fputs($fp, "\n$s\n\n");
  2809. fclose($fp);
  2810. }
  2811. }
  2812. function w2p_pluralize($word)
  2813. {
  2814. $rules= array(
  2815. '/(matr|vert|ind)(ix|ex)$/i' => '\1ices', # matrix, vertex, index
  2816. '/(ss|sh|ch|x|z)$/i' => '\1es', # sibilant rule (no ending e)
  2817. '/([^aeiou])o$/i' => '\1oes', # -oes rule
  2818. '/([^aeiou]|qu)y$/i' => '\1ies', # -ies rule
  2819. '/sis$/i' => 'ses', # synopsis, diagnosis
  2820. '/(m|l)ouse$/i' => '\1ice', # mouse, louse
  2821. '/(t|i)um$/i' => '\1a', # datum, medium
  2822. '/([li])fe?$/i' => '\1ves', # knife, life, shelf
  2823. '/(octop|vir|syllab)us$/i' => '\1i', # octopus, virus, syllabus
  2824. '/(ax|test)is$/i' => '\1es', # axis, testis
  2825. '/([a-rt-z])$/i' => '\1s' # not ending in s
  2826. );
  2827. $irregulars = array(
  2828. 'bus' => 'busses',
  2829. 'child' => 'children',
  2830. 'equipment' => 'equipment',
  2831. 'fish' => 'fish',
  2832. 'information' => 'information',
  2833. 'man' => 'men',
  2834. 'money' => 'money',
  2835. 'moose' => 'moose',
  2836. 'news' => 'news',
  2837. 'person' => 'people',
  2838. 'quiz' => 'quizzes',
  2839. 'rice' => 'rice',
  2840. 'series' => 'series',
  2841. 'sheep' => 'sheep',
  2842. 'species' => 'species',
  2843. 'todo' => 'todos'
  2844. );
  2845. if (isset($irregulars[$word])) {
  2846. return $irregulars[$word];
  2847. }
  2848. foreach ($rules as $regex => $replace) {
  2849. $word = preg_replace($regex, $replace, $word, 1, $count);
  2850. if ($count) {
  2851. return $word;
  2852. }
  2853. }
  2854. return $word;
  2855. }
  2856. function seconds2HM($sec, $padHours = true)
  2857. {
  2858. $HM = "";
  2859. // there are 3600 seconds in an hour, so if we
  2860. // divide total seconds by 3600 and throw away
  2861. // the remainder, we've got the number of hours
  2862. $hours = (int) ($sec / 3600);
  2863. // with the remaining seconds divide them by 60
  2864. // and then round the floating number to get the precise minute
  2865. $minutes = intval(round(($sec - ($hours * 3600)) / 60) ,0);
  2866. if (intval($hours) == 0 && intval($minutes) < 0) {
  2867. $HM .= '-0:';
  2868. } else {
  2869. // add to $hms, with a leading 0 if asked for
  2870. $HM .= ($padHours) ? str_pad($hours, 2, "0", STR_PAD_LEFT). ':' : $hours. ':';
  2871. }
  2872. if (intval($hours) < 0 || intval($minutes) < 0) {
  2873. $minutes = $minutes * (-1);
  2874. }
  2875. $HM .= str_pad($minutes, 2, "0", STR_PAD_LEFT);
  2876. return $HM;
  2877. }
  2878. function HM2seconds($HM)
  2879. {
  2880. list($h, $m) = explode (":", $HM);
  2881. if (intval($h) > 23 && intval($h) < 0) $h = 0;
  2882. if (intval($m) > 59 && intval($m) < 0) $m = 0;
  2883. $seconds = 0;
  2884. $seconds += (intval($h) * 3600);
  2885. $seconds += (intval($m) * 60);
  2886. return $seconds;
  2887. }
  2888. /**
  2889. * Parse the SQL file and get out the timezones from it to use it on the install
  2890. * screen. The SQL file used is: install/sql/mysql/018_add_timezones.sql
  2891. */
  2892. function w2PgetTimezonesForInstall()
  2893. {
  2894. $file = W2P_BASE_DIR . '/install/sql/018_add_timezones.sql';
  2895. $timezones = array();
  2896. if (is_file($file) and is_readable($file)) {
  2897. $sql = file_get_contents($file);
  2898. // get it from this kind of a string:
  2899. // (1, 'Timezones', 'Pacific/Auckland', 43200);
  2900. preg_match_all("#\(.*Timezones',\s*'(.*)',.*\);#", $sql, $matchedTimezones);
  2901. sort($matchedTimezones[1]);
  2902. foreach ($matchedTimezones[1] as $timezone) {
  2903. $timezones[$timezone] = $timezone;
  2904. }
  2905. }
  2906. return $timezones;
  2907. }
  2908. //
  2909. // New password code based oncode from Mambo Open Source Core
  2910. // www.mamboserver.com | mosforge.net
  2911. //
  2912. function sendNewPass()
  2913. {
  2914. global $AppUI;
  2915. // ensure no malicous sql gets past
  2916. $checkusername = preg_replace("/[^A-Za-z0-9]/", "", w2PgetParam($_POST, 'checkusername', ''));
  2917. $confirmEmail = trim(w2PgetParam($_POST, 'checkemail', ''));
  2918. $confirmEmail = strtolower(db_escape($confirmEmail));
  2919. $q = new w2p_Database_Query;
  2920. $q->addTable('users');
  2921. $q->addJoin('contacts', 'con', 'user_contact = contact_id', 'inner');
  2922. $q->addQuery('user_id');
  2923. $q->addWhere("user_username = '$checkusername'");
  2924. /* Begin Hack */
  2925. /*
  2926. * This is a particularly annoying hack but I don't know of a better
  2927. * way to resolve #457. In v2.0, there was a refactoring to allow for
  2928. * muliple contact methods which resulted in the contact_email being
  2929. * removed from the contacts table. If the user is upgrading from
  2930. * v1.x and they try to log in before applying the database, crash.
  2931. * Info: http://bugs.web2project.net/view.php?id=457
  2932. */
  2933. $qTest = new w2p_Database_Query();
  2934. $qTest->addTable('w2pversion');
  2935. $qTest->addQuery('max(db_version)');
  2936. $dbVersion = $qTest->loadResult();
  2937. if ($dbVersion >= 21 && $dbVersion < 26) {
  2938. $q->leftJoin('contacts_methods', 'cm', 'cm.contact_id = con.contact_id');
  2939. $q->addWhere("cm.method_value = '$confirmEmail'");
  2940. } else {
  2941. $q->addWhere("LOWER(user_email) = '$confirmEmail'");
  2942. }
  2943. /* End Hack */
  2944. $user_id = $q->loadResult();
  2945. if (!$user_id) {
  2946. $AppUI->setMsg('Invalid username or email.', UI_MSG_ERROR);
  2947. $AppUI->redirect();
  2948. }
  2949. $auth = new w2p_Authenticators_SQL();
  2950. $newpass = $auth->createNewPassword();
  2951. $hashed = $auth->hashPassword($newpass);
  2952. $q->addTable('users');
  2953. $q->addUpdate('user_password', $hashed);
  2954. $q->addWhere('user_id=' . $user_id);
  2955. $cur = $q->exec();
  2956. if ($cur) {
  2957. $emailManager = new w2p_Output_EmailManager($AppUI);
  2958. $body = $emailManager->notifyPasswordReset($checkusername, $newpass);
  2959. $m = new w2p_Utilities_Mail; // create the mail
  2960. $m->To($confirmEmail);
  2961. $subject = $_sitename . ' :: ' . $AppUI->_('sendpass4', UI_OUTPUT_RAW) . ' - ' . $checkusername;
  2962. $m->Subject($subject);
  2963. $m->Body($body, isset($GLOBALS['locale_char_set']) ? $GLOBALS['locale_char_set'] : ''); // set the body
  2964. $m->Send(); // send the mail
  2965. $AppUI->setMsg('New User Password created and emailed to you');
  2966. $AppUI->redirect();
  2967. }
  2968. }
  2969. // from modules/reports/overall.php
  2970. function showcompany($company_id, $restricted = false)
  2971. {
  2972. global $AppUI, $allpdfdata, $log_start_date, $log_end_date, $log_all;
  2973. $q = new w2p_Database_Query;
  2974. $q->addTable('projects');
  2975. $q->addQuery('project_id, project_name');
  2976. $q->addWhere('project_company = ' . (int) $company_id);
  2977. $projects = $q->loadHashList();
  2978. $q->clear();
  2979. $company = new CCompany();
  2980. $company->load($company_id);
  2981. $company_name = $company->company_name;
  2982. $table = '<h2>Company: ' . $company_name . '</h2>
  2983. <table cellspacing="1" cellpadding="4" border="0" class="tbl">';
  2984. $project_row = '
  2985. <tr>
  2986. <th>' . $AppUI->_('Project') . '</th>';
  2987. $pdfth[] = $AppUI->_('Project');
  2988. $project_row .= '<th>' . $AppUI->_('Total') . '</th></tr>';
  2989. $pdfth[] = $AppUI->_('Total');
  2990. $pdfdata[] = $pdfth;
  2991. $hours = 0.0;
  2992. $table .= $project_row;
  2993. foreach ($projects as $project => $name) {
  2994. $pdfproject = array();
  2995. $pdfproject[] = $name;
  2996. $project_hours = 0;
  2997. $project_row = '<tr><td>' . $name . '</td>';
  2998. $q->addTable('projects');
  2999. $q->addTable('tasks');
  3000. $q->addTable('task_log');
  3001. $q->addQuery('task_log_costcode, SUM(task_log_hours) as hours');
  3002. $q->addWhere('project_id = ' . (int) $project);
  3003. $q->addWhere('project_active = 1');
  3004. if (($template_status = w2PgetConfig('template_projects_status_id')) != '') {
  3005. $q->addWhere('project_status <> ' . (int) $template_status);
  3006. }
  3007. if ($log_start_date != 0 && !$log_all) {
  3008. $q->addWhere('task_log_date >=' . $log_start_date);
  3009. }
  3010. if ($log_end_date != 0 && !$log_all) {
  3011. $q->addWhere('task_log_date <=' . $log_end_date);
  3012. }
  3013. if ($restricted) {
  3014. $q->addWhere('task_log_creator = ' . (int) $AppUI->user_id);
  3015. }
  3016. $q->addWhere('project_id = task_project');
  3017. $q->addWhere('task_id = task_log_task');
  3018. $q->addGroup('project_id');
  3019. $task_logs = $q->loadHashList();
  3020. $q->clear();
  3021. foreach ($task_logs as $task_log) {
  3022. $project_hours += $task_log;
  3023. }
  3024. $project_row .= '<td style="text-align:right;">' . sprintf('%.2f', round($project_hours, 2)) . '</td></tr>';
  3025. $pdfproject[] = round($project_hours, 2);
  3026. $hours += $project_hours;
  3027. if ($project_hours > 0) {
  3028. $table .= $project_row;
  3029. $pdfdata[] = $pdfproject;
  3030. }
  3031. }
  3032. if ($hours > 0) {
  3033. $pdfdata[] = array($AppUI->_('Total'), round($hours, 2));
  3034. $allpdfdata[$company_name] = $pdfdata;
  3035. echo $table;
  3036. echo '<tr><td>' . $AppUI->_('Total') . '</td><td style="text-align:right;">' . sprintf('%.2f', round($hours, 2)) . '</td></tr></table>';
  3037. }
  3038. return $hours;
  3039. }
  3040. /**
  3041. * Sub-function to collect events within a period
  3042. * @param Date the starting date of the period
  3043. * @param Date the ending date of the period
  3044. * @param array by-ref an array of links to append new items to
  3045. * @param int the length to truncate entries by
  3046. * @author Andrew Eddie <eddieajau@users.sourceforge.net>
  3047. */
  3048. function getEventLinks($startPeriod, $endPeriod, $links, $notUsed = null, $minical = false)
  3049. {
  3050. global $event_filter;
  3051. $events = CEvent::getEventsForPeriod($startPeriod, $endPeriod, $event_filter);
  3052. $cwd = explode(',', w2PgetConfig('cal_working_days'));
  3053. // assemble the links for the events
  3054. foreach ($events as $row) {
  3055. $start = new w2p_Utilities_Date($row['event_start_date']);
  3056. $end = new w2p_Utilities_Date($row['event_end_date']);
  3057. $date = $start;
  3058. for ($i = 0, $i_cmp = $start->dateDiff($end); $i <= $i_cmp; $i++) {
  3059. // the link
  3060. // optionally do not show events on non-working days
  3061. if (($row['event_cwd'] && in_array($date->getDayOfWeek(), $cwd)) || !$row['event_cwd']) {
  3062. if ($minical) {
  3063. $link = array();
  3064. } else {
  3065. $url = '?m=events&a=view&event_id=' . $row['event_id'];
  3066. $link['href'] = '';
  3067. $link['alt'] = '';
  3068. $link['text'] = w2PtoolTip($row['event_name'], getEventTooltip($row['event_id']), true) . w2PshowImage('modules/events/event' . $row['event_type'] . '.png', 16, 16, '', '', 'calendar') . '</a>&nbsp;' . '<a href="' . $url . '"><span class="event">' . $row['event_name'] . '</span></a>' . w2PendTip();
  3069. }
  3070. $links[$date->format(FMT_TIMESTAMP_DATE)][] = $link;
  3071. }
  3072. $date = $date->getNextDay();
  3073. }
  3074. }
  3075. return $links;
  3076. }
  3077. function getEventTooltip($event_id)
  3078. {
  3079. global $AppUI;
  3080. if (!$event_id) {
  3081. return '';
  3082. }
  3083. $df = $AppUI->getPref('SHDATEFORMAT');
  3084. $tf = $AppUI->getPref('TIMEFORMAT');
  3085. // load the record data
  3086. $event = new CEvent();
  3087. $event->loadFull($event_id);
  3088. // load the event types
  3089. $types = w2PgetSysVal('EventType');
  3090. // load the event recurs types
  3091. $recurs = array('Never', 'Hourly', 'Daily', 'Weekly', 'Bi-Weekly', 'Every Month', 'Quarterly', 'Every 6 months', 'Every Year');
  3092. $obj = new CEvent();
  3093. $obj->event_id = $event_id;
  3094. $assigned = $obj->getAssigned();
  3095. if ($event->event_project) {
  3096. $event_project = $event->project_name;
  3097. $event_company = $event->company_name;
  3098. }
  3099. $tt = '<table class="tool-tip">';
  3100. $tt .= '<tr>';
  3101. $tt .= ' <td valign="top" width="40%">';
  3102. $tt .= ' <strong>' . $AppUI->_('Details') . '</strong>';
  3103. $tt .= ' <table cellspacing="3" cellpadding="2" width="100%">';
  3104. $tt .= ' <tr>';
  3105. $tt .= ' <td class="tip-label">' . $AppUI->_('Type') . '</td>';
  3106. $tt .= ' <td>' . $AppUI->_($types[$event->event_type]) . '</td>';
  3107. $tt .= ' </tr> ';
  3108. if ($event->event_project) {
  3109. $tt .= ' <tr>';
  3110. $tt .= ' <td class="tip-label">' . $AppUI->_('Company') . '</td>';
  3111. $tt .= ' <td>' . $event_company . '</td>';
  3112. $tt .= ' </tr>';
  3113. $tt .= ' <tr>';
  3114. $tt .= ' <td class="tip-label">' . $AppUI->_('Project') . '</td>';
  3115. $tt .= ' <td>' . $event_project . '</td>';
  3116. $tt .= ' </tr>';
  3117. }
  3118. $tt .= ' <tr>';
  3119. $tt .= ' <td class="tip-label">' . $AppUI->_('Starts') . '</td>';
  3120. $tt .= ' <td>' . $AppUI->formatTZAwareTime($event->event_start_date, $df . ' ' . $tf) . '</td>';
  3121. $tt .= ' </tr>';
  3122. $tt .= ' <tr>';
  3123. $tt .= ' <td class="tip-label">' . $AppUI->_('Ends') . '</td>';
  3124. $tt .= ' <td>' . $AppUI->formatTZAwareTime($event->event_end_date, $df . ' ' . $tf) . '</td>';
  3125. $tt .= ' </tr>';
  3126. $tt .= ' <tr>';
  3127. $tt .= ' <td class="tip-label">' . $AppUI->_('Recurs') . '</td>';
  3128. $tt .= ' <td>' . $AppUI->_($recurs[$event->event_recurs]) . ($event->event_recurs ? ' (' . $event->event_times_recuring . '&nbsp;' . $AppUI->_('times') . ')' : '') . '</td>';
  3129. $tt .= ' </tr>';
  3130. $tt .= ' <tr>';
  3131. $tt .= ' <td class="tip-label">' . $AppUI->_('Attendees') . '</td>';
  3132. $tt .= ' <td>';
  3133. $tt .= implode('<br />', $assigned);
  3134. $tt .= ' </tr>';
  3135. $tt .= ' </table>';
  3136. $tt .= ' </td>';
  3137. $tt .= ' <td width="60%" valign="top">';
  3138. $tt .= ' <strong>' . $AppUI->_('Note') . '</strong>';
  3139. $tt .= ' <table cellspacing="0" cellpadding="2" border="0" width="100%">';
  3140. $tt .= ' <tr>';
  3141. $tt .= ' <td class="tip-label description">';
  3142. $tt .= ' ' . mb_str_replace(chr(10), "<br />", $event->event_description) . '&nbsp;';
  3143. $tt .= ' </td>';
  3144. $tt .= ' </tr>';
  3145. $tt .= ' </table>';
  3146. $tt .= ' </td>';
  3147. $tt .= '</tr>';
  3148. $tt .= '</table>';
  3149. return $tt;
  3150. }
  3151. /**
  3152. * Sub-function to collect tasks within a period
  3153. *
  3154. * @param Date the starting date of the period
  3155. * @param Date the ending date of the period
  3156. * @param array by-ref an array of links to append new items to
  3157. * @param int the length to truncate entries by
  3158. * @param int the company id to filter by
  3159. * @author Andrew Eddie <eddieajau@users.sourceforge.net>
  3160. */
  3161. function getTaskLinks($startPeriod, $endPeriod, $links, $strMaxLen, $company_id = 0, $minical = false, $userid=0)
  3162. {
  3163. global $a, $AppUI;
  3164. $tasks = CTask::getTasksForPeriod($startPeriod, $endPeriod, $company_id, $userid);
  3165. $tf = $AppUI->getPref('TIMEFORMAT');
  3166. //subtract one second so we don't have to compare the start dates for exact matches with the startPeriod which is 00:00 of a given day.
  3167. $startPeriod->subtractSeconds(1);
  3168. $link = array();
  3169. // assemble the links for the tasks
  3170. foreach ($tasks as $row) {
  3171. // the link
  3172. $link['task'] = true;
  3173. if (!$minical) {
  3174. $link['href'] = '?m=tasks&a=view&task_id=' . $row['task_id'];
  3175. // the link text
  3176. if (mb_strlen($row['task_name']) > $strMaxLen) {
  3177. $row['short_name'] = mb_substr($row['task_name'], 0, $strMaxLen) . '...';
  3178. } else {
  3179. $row['short_name'] = $row['task_name'];
  3180. }
  3181. $link['text'] = '<span style="color:' . bestColor($row['color']) . ';background-color:#' . $row['color'] . '">' . $row['short_name'] . ($row['task_milestone'] ? '&nbsp;' . w2PshowImage('icons/milestone.gif') : '') . '</span>';
  3182. }
  3183. // determine which day(s) to display the task
  3184. $start = new w2p_Utilities_Date($AppUI->formatTZAwareTime($row['task_start_date'], '%Y-%m-%d %T'));
  3185. $end = $row['task_end_date'] ? new w2p_Utilities_Date($AppUI->formatTZAwareTime($row['task_end_date'], '%Y-%m-%d %T')) : null;
  3186. // First we test if the Tasks Starts and Ends are on the same day, if so we don't need to go any further.
  3187. if (($start->after($startPeriod)) && ($end && $end->after($startPeriod) && $end->before($endPeriod) && !($start->dateDiff($end)))) {
  3188. if ($minical) {
  3189. $temp = array('task' => true);
  3190. } else {
  3191. $temp = $link;
  3192. if ($a != 'day_view') {
  3193. $temp['text'] = w2PtoolTip($row['task_name'], getTaskTooltip($row['task_id']), true) . w2PshowImage('block-start-16.png') . $start->format($tf) . ' ' . $temp['text'] . ' ' . $end->format($tf) . w2PshowImage('block-end-16.png') . w2PendTip();
  3194. $temp['text'].= '<a href="?m=tasks&amp;a=view&amp;task_id=' . $row['task_id'] . '&amp;tab=1&amp;date=' . $AppUI->formatTZAwareTime($row['task_end_date'], '%Y%m%d'). '">' . w2PtoolTip('Add Log', 'create a new log record against this task') . w2PshowImage('edit_add.png') . w2PendTip() . '</a>';
  3195. }
  3196. }
  3197. $links[$end->format(FMT_TIMESTAMP_DATE)][] = $temp;
  3198. } else {
  3199. // If they aren't, we will now need to see if the Tasks Start date is between the requested period
  3200. if ($start->after($startPeriod) && $start->before($endPeriod)) {
  3201. if ($minical) {
  3202. $temp = array('task' => true);
  3203. } else {
  3204. $temp = $link;
  3205. if ($a != 'day_view') {
  3206. $temp['text'] = w2PtoolTip($row['task_name'], getTaskTooltip($row['task_id']), true) . w2PshowImage('block-start-16.png') . $start->format($tf) . ' ' . $temp['text'] . w2PendTip();
  3207. $temp['text'].= '<a href="?m=tasks&amp;a=view&amp;task_id=' . $row['task_id'] . '&amp;tab=1&amp;date=' . $AppUI->formatTZAwareTime($row['task_start_date'], '%Y%m%d'). '">' . w2PtoolTip('Add Log', 'create a new log record against this task') . w2PshowImage('edit_add.png') . w2PendTip() . '</a>';
  3208. }
  3209. }
  3210. $links[$start->format(FMT_TIMESTAMP_DATE)][] = $temp;
  3211. }
  3212. // And now the Tasks End date is checked if it is between the requested period too.
  3213. if ($end && $end->after($startPeriod) && $end->before($endPeriod) && $start->before($end)) {
  3214. if ($minical) {
  3215. $temp = array('task' => true);
  3216. } else {
  3217. $temp = $link;
  3218. if ($a != 'day_view') {
  3219. $temp['text'] = w2PtoolTip($row['task_name'], getTaskTooltip($row['task_id']), true) . ' ' . $temp['text'] . ' ' . $end->format($tf) . w2PshowImage('block-end-16.png') . w2PendTip();
  3220. $temp['text'].= '<a href="?m=tasks&amp;a=view&amp;task_id=' . $row['task_id'] . '&amp;tab=1&amp;date=' . $AppUI->formatTZAwareTime($row['task_end_date'], '%Y%m%d'). '">' . w2PtoolTip('Add Log', 'create a new log record against this task') . w2PshowImage('edit_add.png') . w2PendTip() . '</a>';
  3221. }
  3222. }
  3223. $links[$end->format(FMT_TIMESTAMP_DATE)][] = $temp;
  3224. }
  3225. }
  3226. }
  3227. return $links;
  3228. }
  3229. function getTaskTooltip($task_id)
  3230. {
  3231. global $AppUI;
  3232. if (!$task_id) {
  3233. return '';
  3234. }
  3235. $df = $AppUI->getPref('SHDATEFORMAT');
  3236. $tf = $AppUI->getPref('TIMEFORMAT');
  3237. $task = new CTask();
  3238. // load the record data
  3239. $task->load($task_id);
  3240. // load the event types
  3241. $types = w2PgetSysVal('TaskType');
  3242. $assignees = $task->assignees($task_id);
  3243. $assigned = array();
  3244. foreach ($assignees as $user) {
  3245. $assigned[] = $user['contact_name'] . ' ' . $user['perc_assignment'] . '%';
  3246. }
  3247. $start_date = (int) $task->task_start_date ? new w2p_Utilities_Date($AppUI->formatTZAwareTime($task->task_start_date, '%Y-%m-%d %T')) : null;
  3248. $end_date = (int) $task->task_end_date ? new w2p_Utilities_Date($AppUI->formatTZAwareTime($task->task_end_date, '%Y-%m-%d %T')) : null;
  3249. // load the record data
  3250. $project = new CProject();
  3251. $project->load($task->task_project);
  3252. $task_project = $project->project_name;
  3253. $company = new CCompany();
  3254. $company->load($project->project_company);
  3255. $task_company = $company->company_name;
  3256. $tt = '<table class="tool-tip">';
  3257. $tt .= '<tr>';
  3258. $tt .= ' <td valign="top" width="40%">';
  3259. $tt .= ' <strong>' . $AppUI->_('Details') . '</strong>';
  3260. $tt .= ' <table cellspacing="3" cellpadding="2" width="100%">';
  3261. $tt .= ' <tr>';
  3262. $tt .= ' <td class="tip-label">' . $AppUI->_('Company') . '</td>';
  3263. $tt .= ' <td>' . $task_company . '</td>';
  3264. $tt .= ' </tr>';
  3265. $tt .= ' <tr>';
  3266. $tt .= ' <td class="tip-label">' . $AppUI->_('Project') . '</td>';
  3267. $tt .= ' <td>' . $task_project . '</td>';
  3268. $tt .= ' </tr>';
  3269. $tt .= ' <tr>';
  3270. $tt .= ' <td class="tip-label">' . $AppUI->_('Type') . '</td>';
  3271. $tt .= ' <td>' . $AppUI->_($types[$task->task_type]) . '</td>';
  3272. $tt .= ' </tr> ';
  3273. $tt .= ' <tr>';
  3274. $tt .= ' <td class="tip-label">' . $AppUI->_('Progress') . '</td>';
  3275. $tt .= ' <td>' . sprintf("%.1f%%", $task->task_percent_complete) . '</td>';
  3276. $tt .= ' </tr> ';
  3277. $tt .= ' <tr>';
  3278. $tt .= ' <td class="tip-label">' . $AppUI->_('Starts') . '</td>';
  3279. $tt .= ' <td>' . ($start_date ? $start_date->format($df . ' ' . $tf) : '-') . '</td>';
  3280. $tt .= ' </tr>';
  3281. $tt .= ' <tr>';
  3282. $tt .= ' <td class="tip-label">' . $AppUI->_('Ends') . '</td>';
  3283. $tt .= ' <td>' . ($end_date ? $end_date->format($df . ' ' . $tf) : '-') . '</td>';
  3284. $tt .= ' </tr>';
  3285. $tt .= ' <tr>';
  3286. $tt .= ' <td class="tip-label">' . $AppUI->_('Assignees') . '</td>';
  3287. $tt .= ' <td>';
  3288. $tt .= implode('<br />', $assigned);
  3289. $tt .= ' </tr>';
  3290. $tt .= ' </table>';
  3291. $tt .= ' </td>';
  3292. $tt .= ' <td width="60%" valign="top">';
  3293. $tt .= ' <strong>' . $AppUI->_('Description') . '</strong>';
  3294. $tt .= ' <table cellspacing="0" cellpadding="2" border="0" width="100%">';
  3295. $tt .= ' <tr>';
  3296. $tt .= ' <td class="tip-label description">';
  3297. $tt .= ' ' . $task->task_description;
  3298. $tt .= ' </td>';
  3299. $tt .= ' </tr>';
  3300. $tt .= ' </table>';
  3301. $tt .= ' </td>';
  3302. $tt .= '</tr>';
  3303. $tt .= '</table>';
  3304. return $tt;
  3305. }
  3306. /**
  3307. * @param $perms
  3308. * @param $user_id
  3309. * @param $module
  3310. * @param $action
  3311. *
  3312. * @return array
  3313. */
  3314. function getPermissions($perms, $user_id, $module, $action)
  3315. {
  3316. $q = new w2p_Database_Query;
  3317. $q->addTable($perms->_db_acl_prefix . 'permissions', 'gp');
  3318. $q->addQuery('gp.*');
  3319. $q->addWhere('user_id = ' . $user_id);
  3320. if ('all' != $module) {
  3321. $q->addWhere("module = '$module'");
  3322. }
  3323. if ('all' != $action) {
  3324. $q->addWhere("action = '$action'");
  3325. }
  3326. $q->addOrder('user_name');
  3327. $q->addOrder('module');
  3328. $q->addOrder('action');
  3329. $q->addOrder('item_id');
  3330. $q->addOrder('acl_id');
  3331. $permissions = $q->loadList();
  3332. return $permissions;
  3333. }
  3334. /**
  3335. * @param $row
  3336. *
  3337. * @return array
  3338. */
  3339. function getPermissionField($row)
  3340. {
  3341. $q = new w2p_Database_Query;
  3342. $q->addTable('modules');
  3343. $q->addQuery('permissions_item_field,permissions_item_label');
  3344. $q->addWhere('mod_directory = \'' . $row['module'] . '\'');
  3345. $field = $q->loadHash();
  3346. return $field;
  3347. }
  3348. /**
  3349. * @param $row
  3350. * @param $field
  3351. *
  3352. * @return Value
  3353. */
  3354. function getPermissionItem($row, $field)
  3355. {
  3356. $q = new w2p_Database_Query;
  3357. $q->addTable($row['module']);
  3358. $q->addQuery($field['permissions_item_label']);
  3359. $q->addWhere($field['permissions_item_field'] . ' = \'' . $row['item_id'] . '\'');
  3360. $item = $q->loadResult();
  3361. return $item;
  3362. }
  3363. /**
  3364. * @param $user_id
  3365. *
  3366. * @return array
  3367. */
  3368. function getPreferences($user_id)
  3369. {
  3370. $q = new w2p_Database_Query;
  3371. $q->addTable('user_preferences');
  3372. $q->addQuery('pref_name, pref_value');
  3373. $q->addWhere('pref_user = ' . (int) $user_id);
  3374. $prefs = $q->loadHashList();
  3375. return $prefs;
  3376. }
  3377. /**
  3378. * @param $obj
  3379. *
  3380. * @return array
  3381. */
  3382. function getTaskLogContacts($obj)
  3383. {
  3384. $q = new w2p_Database_Query();
  3385. $q->addTable('task_contacts', 'tc');
  3386. $q->addJoin('contacts', 'c', 'c.contact_id = tc.contact_id', 'inner');
  3387. $q->addWhere('tc.task_id = ' . (int) $obj->task_id);
  3388. $q->addQuery('tc.contact_id');
  3389. $q->addQuery('c.contact_first_name, c.contact_last_name');
  3390. $req = & $q->exec();
  3391. return $req;
  3392. }
  3393. /**
  3394. * @param $obj
  3395. *
  3396. * @return array
  3397. */
  3398. function getContactsfromProjects($obj)
  3399. {
  3400. $q = new w2p_Database_Query();
  3401. $q->addTable('project_contacts', 'pc');
  3402. $q->addJoin('contacts', 'c', 'c.contact_id = pc.contact_id', 'inner');
  3403. $q->addWhere('pc.project_id = ' . (int) $obj->task_project);
  3404. $q->addQuery('pc.contact_id');
  3405. $q->addQuery('c.contact_first_name, c.contact_last_name');
  3406. $req = & $q->exec();
  3407. return $req;
  3408. }
  3409. /**
  3410. * @param $project_id
  3411. * @param $AppUI
  3412. *
  3413. * @return Associative
  3414. */
  3415. function __extract_from_tasks_viewgantt($project_id, $AppUI)
  3416. {
  3417. $q = new w2p_Database_Query;
  3418. $q->addTable('tasks', 't');
  3419. $q->addJoin('projects', 'p', 'p.project_id = t.task_project');
  3420. $q->addQuery('t.task_id, task_parent, task_name, task_start_date, task_end_date'
  3421. . ', task_duration, task_duration_type, task_priority, task_percent_complete'
  3422. . ', task_order, task_project, task_milestone, project_name, task_dynamic');
  3423. $q->addWhere('project_status != 7 AND task_dynamic = 1');
  3424. if ($project_id) {
  3425. $q->addWhere('task_project = ' . $project_id);
  3426. }
  3427. $task = new CTask;
  3428. $q = $task->setAllowedSQL($AppUI->user_id, $q);
  3429. $proTasks = $q->loadHashList('task_id');
  3430. return $proTasks;
  3431. }
  3432. /**
  3433. * @param $user_id
  3434. * @param $showArcProjs
  3435. * @param $showLowTasks
  3436. * @param $showInProgress
  3437. * @param $showHoldProjs
  3438. * @param $showDynTasks
  3439. * @param $showPinned
  3440. * @param $showEmptyDate
  3441. * @param $task_type
  3442. * @param $allowedTasks
  3443. * @param $allowedProjects
  3444. *
  3445. * @return Array
  3446. */
  3447. function __extract_from_todo($user_id, $showArcProjs, $showLowTasks, $showInProgress, $showHoldProjs, $showDynTasks, $showPinned, $showEmptyDate, $task_type, $allowedTasks, $allowedProjects)
  3448. {
  3449. // query my sub-tasks (ignoring task parents)
  3450. $q = new w2p_Database_Query;
  3451. $q->addQuery('distinct(ta.task_id), ta.*, ta.task_start_date as task_start_datetime, ta.task_end_date as task_end_datetime');
  3452. $q->addQuery('project_name, pr.project_id, project_color_identifier');
  3453. $q->addQuery('tp.task_pinned');
  3454. $q->addQuery('ut.user_task_priority');
  3455. $dateDiffString = $q->dbfnDateDiff('ta.task_end_date', $q->dbfnNow()) . ' AS task_due_in';
  3456. $q->addQuery($dateDiffString);
  3457. $q->addTable('projects', 'pr');
  3458. $q->addTable('tasks', 'ta');
  3459. $q->addTable('user_tasks', 'ut');
  3460. $q->leftJoin('user_task_pin', 'tp', 'tp.task_id = ta.task_id and tp.user_id = ' . (int) $user_id);
  3461. $q->addWhere('ut.task_id = ta.task_id');
  3462. $q->addWhere('ut.user_id = ' . (int) $user_id);
  3463. $q->addWhere('( ta.task_percent_complete < 100 or ta.task_percent_complete is null)');
  3464. $q->addWhere('ta.task_status = 0');
  3465. $q->addWhere('pr.project_id = ta.task_project');
  3466. if (!$showArcProjs) {
  3467. $q->addWhere('project_active = 1');
  3468. if (($template_status = w2PgetConfig('template_projects_status_id')) != '') {
  3469. $q->addWhere('project_status <> ' . (int) $template_status);
  3470. }
  3471. }
  3472. if (!$showLowTasks) {
  3473. $q->addWhere('task_priority >= 0');
  3474. }
  3475. if ($showInProgress) {
  3476. $q->addWhere('project_status = 3');
  3477. }
  3478. if (!$showHoldProjs) {
  3479. if (($on_hold_status = w2PgetConfig('on_hold_projects_status_id')) != '') {
  3480. $q->addWhere('project_status <> ' . (int) $on_hold_status);
  3481. }
  3482. }
  3483. if (!$showDynTasks) {
  3484. $q->addWhere('task_dynamic <> 1');
  3485. }
  3486. if ($showPinned) {
  3487. $q->addWhere('task_pinned = 1');
  3488. }
  3489. if (!$showEmptyDate) {
  3490. $q->addWhere('ta.task_start_date <> \'\' AND ta.task_start_date <> \'0000-00-00 00:00:00\'');
  3491. }
  3492. if ($task_type != '') {
  3493. $q->addWhere('ta.task_type = ' . (int) $task_type);
  3494. }
  3495. if (count($allowedTasks)) {
  3496. $q->addWhere($allowedTasks);
  3497. }
  3498. if (count($allowedProjects)) {
  3499. $q->addWhere($allowedProjects);
  3500. }
  3501. $q->addOrder('task_end_date, task_start_date, task_priority');
  3502. $tasks = $q->loadList();
  3503. return $tasks;
  3504. }
  3505. /**
  3506. * @param $use_period
  3507. * @param $ss
  3508. * @param $se
  3509. * @param $log_userfilter
  3510. * @param $project_id
  3511. * @param $company_id
  3512. * @param $proj
  3513. * @param $AppUI
  3514. *
  3515. * @return mixed
  3516. */
  3517. function __extract_from_tasksperuser($use_period, $ss, $se, $log_userfilter, $project_id, $company_id, $proj, $AppUI, $all_proj_status='on')
  3518. {
  3519. $q = new w2p_Database_Query;
  3520. $q->addTable('tasks', 't');
  3521. $q->addQuery('t.*');
  3522. $q->addJoin('projects', 'pr', 'pr.project_id = t.task_project', 'inner');
  3523. $q->addWhere('pr.project_active = 1');
  3524. if ('off'==$all_proj_status) {
  3525. $q->addWhere('pr.project_status = 3 ');
  3526. }
  3527. else {
  3528. if (($template_status = w2PgetConfig('template_projects_status_id')) != '') {
  3529. $q->addWhere('pr.project_status <> ' . (int) $template_status);
  3530. }
  3531. }
  3532. if ('on' == $use_period) {
  3533. $q->addWhere('(( task_start_date >= ' . $ss . ' AND task_start_date <= ' . $se . ' ) OR ' . ' ( task_end_date <= ' . $se . ' AND task_end_date >= ' . $ss . ' ))');
  3534. }
  3535. $q->addWhere('(task_percent_complete < 100)');
  3536. $q->addJoin('user_tasks', 'ut', 'ut.task_id = t.task_id');
  3537. if ($log_userfilter > -1) {
  3538. $q->addWhere('ut.user_id = ' . $log_userfilter);
  3539. }
  3540. if ($project_id != 'all') {
  3541. $q->addWhere('t.task_project=' . (int) $project_id);
  3542. }
  3543. if ($company_id != 'all') {
  3544. $q->addWhere('pr.project_company = ' . (int) $company_id);
  3545. }
  3546. $q->addOrder('task_project');
  3547. $q->addOrder('task_end_date');
  3548. $q->addOrder('task_start_date');
  3549. $q = $proj->setAllowedSQL($AppUI->user_id, $q, null, 'pr');
  3550. $task_list_hash = $q->loadHashList('task_id');
  3551. return $task_list_hash;
  3552. }
  3553. /**
  3554. * @return String
  3555. */
  3556. function __extract_from_tasks1()
  3557. {
  3558. //subquery the parent state
  3559. $sq = new w2p_Database_Query;
  3560. $sq->addTable('tasks', 'stasks');
  3561. $sq->addQuery('COUNT(stasks.task_id)');
  3562. $sq->addWhere('stasks.task_id <> tasks.task_id AND stasks.task_parent = tasks.task_id');
  3563. $subquery = $sq->prepare();
  3564. return $subquery;
  3565. }
  3566. /**
  3567. * @param $userFilter
  3568. * @param $AppUI
  3569. * @param $proj
  3570. *
  3571. * @return Array
  3572. */
  3573. function __extract_from_listtasks($userFilter, $AppUI, $proj)
  3574. {
  3575. $q = new w2p_Database_Query();
  3576. $q->addQuery('t.task_id, t.task_name');
  3577. $q->addTable('tasks', 't');
  3578. if ($userFilter) {
  3579. $q->addJoin('user_tasks', 'ut', 'ut.task_id = t.task_id');
  3580. $q->addWhere('ut.user_id = ' . (int) $AppUI->user_id);
  3581. }
  3582. if ($proj != 0) {
  3583. $q->addWhere('task_project = ' . (int) $proj);
  3584. }
  3585. $tasks = $q->loadList();
  3586. return $tasks;
  3587. }
  3588. /**
  3589. * @param $selected
  3590. * @param $task_priority
  3591. */
  3592. function __extract_from_tasks_todo($selected, $task_priority)
  3593. {
  3594. $q = new w2p_Database_Query;
  3595. foreach ($selected as $key => $val) {
  3596. if ($task_priority == 'c') {
  3597. // mark task as completed
  3598. $q->addTable('tasks');
  3599. $q->addUpdate('task_percent_complete', '100');
  3600. $q->addWhere('task_id=' . (int) $val);
  3601. } else {
  3602. if ($task_priority == 'd') {
  3603. // delete task
  3604. $q->setDelete('tasks');
  3605. $q->addWhere('task_id=' . (int) $val);
  3606. } else
  3607. if ($task_priority > -2 && $task_priority < 2) {
  3608. // set priority
  3609. $q->addTable('tasks');
  3610. $q->addUpdate('task_priority', $task_priority);
  3611. $q->addWhere('task_id=' . (int) $val);
  3612. }
  3613. }
  3614. $q->exec();
  3615. echo db_error();
  3616. $q->clear();
  3617. }
  3618. }
  3619. /**
  3620. * @return w2p_Database_Query
  3621. */
  3622. function __extract_from_syskeys_index1()
  3623. {
  3624. // pull all the key types
  3625. $q = new w2p_Database_Query;
  3626. $q->addTable('syskeys');
  3627. $q->addQuery('syskey_id,syskey_name');
  3628. $q->addOrder('syskey_name');
  3629. $keys = arrayMerge(array(0 => '- Select Type -'), $q->loadHashList());
  3630. return $keys;
  3631. }
  3632. /**
  3633. * @return array
  3634. */
  3635. function __extract_from_syskeys_index2()
  3636. {
  3637. $q = new w2p_Database_Query;
  3638. $q->addTable('syskeys');
  3639. $q->addTable('sysvals');
  3640. $q->addQuery('DISTINCT sysval_title, sysval_key_id, syskeys.*');
  3641. $q->addWhere('sysval_key_id = syskey_id');
  3642. $q->addOrder('sysval_title');
  3643. $q->addOrder('sysval_id');
  3644. return $q->loadList();
  3645. }
  3646. /**
  3647. * @return Array
  3648. */
  3649. function __extract_from_syskeys_index3()
  3650. {
  3651. $q = new w2p_Database_Query;
  3652. $q->addTable('sysvals');
  3653. $q->addTable('syskeys');
  3654. $q->addQuery('sysval_title, sysval_value_id, sysval_value, syskey_sep1, syskey_sep2');
  3655. $q->addWhere('sysval_key_id = syskey_id');
  3656. $q->addOrder('sysval_title');
  3657. $q->addOrder('sysval_id');
  3658. $vals = $q->loadList();
  3659. return $vals;
  3660. }
  3661. /**
  3662. * @return Array
  3663. */
  3664. function __extract_from_syskeys_syskey()
  3665. {
  3666. $q = new w2p_Database_Query;
  3667. $q->addTable('syskeys');
  3668. $q->addQuery('*');
  3669. $q->addOrder('syskey_name');
  3670. $keys = $q->loadList();
  3671. return $keys;
  3672. }
  3673. function __extract_from_systemconfig_aed()
  3674. {
  3675. // set all checkboxes to false
  3676. // overwrite the true/enabled/checked checkboxes later
  3677. $q = new w2p_Database_Query;
  3678. $q->addTable('config');
  3679. $q->addUpdate('config_value', 'false');
  3680. $q->addWhere("config_type = 'checkbox'");
  3681. $q->loadResult();
  3682. }
  3683. /**
  3684. * @param $hidden_modules
  3685. *
  3686. * @return Array
  3687. */
  3688. function __extract_from_modules_index($hidden_modules)
  3689. {
  3690. $q = new w2p_Database_Query;
  3691. $q->addQuery('*');
  3692. $q->addTable('modules');
  3693. foreach ($hidden_modules as $no_show) {
  3694. $q->addWhere('mod_directory <> \'' . $no_show . '\'');
  3695. }
  3696. $q->addOrder('mod_ui_order');
  3697. $modules = $q->loadList();
  3698. return $modules;
  3699. }
  3700. /**
  3701. * @param $module
  3702. * @param $mod_data
  3703. *
  3704. * @return Value
  3705. */
  3706. function __extract_from_role_perms($module, $mod_data)
  3707. {
  3708. $q = new w2p_Database_Query();
  3709. $q->addTable($module['permissions_item_table']);
  3710. $q->addQuery($module['permissions_item_label']);
  3711. $q->addWhere($module['permissions_item_field'] . '=' . $mod_data['name']);
  3712. $data = $q->loadResult();
  3713. $q->clear();
  3714. return $data;
  3715. }
  3716. /**
  3717. * @param $deps
  3718. *
  3719. * @return Associative
  3720. */
  3721. function __extract_from_ae_depend1($deps)
  3722. {
  3723. $q = new w2p_Database_Query;
  3724. $q->addTable('tasks');
  3725. $q->addQuery('task_id, task_name');
  3726. $q->addWhere('task_id IN (' . $deps . ')');
  3727. $taskDep = $q->loadHashList();
  3728. return $taskDep;
  3729. }
  3730. /**
  3731. * @param $task_id
  3732. *
  3733. * @return Associative
  3734. */
  3735. function __extract_from_ae_depend2($task_id)
  3736. {
  3737. if (0 == (int) $task_id)
  3738. {
  3739. return array();
  3740. }
  3741. $q = new w2p_Database_Query;
  3742. $q->addTable('tasks', 't');
  3743. $q->addTable('task_dependencies', 'td');
  3744. $q->addQuery('t.task_id, t.task_name');
  3745. $q->addWhere('td.dependencies_task_id = ' . (int) $task_id);
  3746. $q->addWhere('t.task_id = td.dependencies_req_task_id');
  3747. $taskDep = $q->loadHashList();
  3748. return $taskDep;
  3749. }
  3750. /**
  3751. * @param $user_id
  3752. * @param $showArcProjs
  3753. * @param $showLowTasks
  3754. * @param $showHoldProjs
  3755. * @param $showDynTasks
  3756. * @param $showPinned
  3757. * @param $task
  3758. * @param $AppUI
  3759. *
  3760. * @return array
  3761. */
  3762. function __extract_from_tasks_gantt1($user_id, $showArcProjs, $showLowTasks, $showHoldProjs, $showDynTasks, $showPinned, $task, $AppUI)
  3763. {
  3764. $q = new w2p_Database_Query;
  3765. $q->addQuery('t.*');
  3766. $q->addQuery('project_name, project_id, project_color_identifier');
  3767. $q->addQuery('tp.task_pinned');
  3768. $q->addTable('tasks', 't');
  3769. $q->innerJoin('projects', 'pr', 'pr.project_id = t.task_project');
  3770. $q->innerJoin('user_tasks', 'ut', 'ut.task_id = t.task_id AND ut.user_id = ' . (int) $user_id);
  3771. $q->leftJoin('user_task_pin', 'tp', 'tp.task_id = t.task_id and tp.user_id = ' . (int) $user_id);
  3772. $q->addWhere('(t.task_percent_complete < 100 OR t.task_percent_complete IS NULL)');
  3773. $q->addWhere('t.task_status = 0');
  3774. if (!$showArcProjs) {
  3775. $q->addWhere('pr.project_active = 1');
  3776. if (($template_status = w2PgetConfig('template_projects_status_id')) != '') {
  3777. $q->addWhere('pr.project_status <> ' . (int) $template_status);
  3778. }
  3779. }
  3780. if (!$showLowTasks) {
  3781. $q->addWhere('task_priority >= 0');
  3782. }
  3783. if (!$showHoldProjs) {
  3784. $q->addWhere('project_active = 1');
  3785. }
  3786. if (!$showDynTasks) {
  3787. $q->addWhere('task_dynamic <> 1');
  3788. }
  3789. if ($showPinned) {
  3790. $q->addWhere('task_pinned = 1');
  3791. }
  3792. $q->addGroup('t.task_id');
  3793. $q->addOrder('t.task_start_date, t.task_end_date, t.task_priority');
  3794. // get any specifically denied tasks
  3795. $q = $task->setAllowedSQL($AppUI->user_id, $q);
  3796. $proTasks = $q->loadHashList('task_id');
  3797. return $proTasks;
  3798. }
  3799. /**
  3800. * @param $showNoMilestones
  3801. * @param $showMilestonesOnly
  3802. * @param $ganttTaskFilter
  3803. * @param $where
  3804. * @param $project_id
  3805. * @param $f
  3806. * @param $AppUI
  3807. * @param $task
  3808. *
  3809. * @return array
  3810. */
  3811. function __extract_from_tasks_gantt2($showNoMilestones, $showMilestonesOnly, $ganttTaskFilter, $where, $project_id, $f, $AppUI, $task)
  3812. {
  3813. // pull tasks
  3814. $q = new w2p_Database_Query;
  3815. $q->addTable('tasks', 't');
  3816. $q->addQuery('t.task_id, task_parent, task_name, task_start_date, task_end_date,' .
  3817. ' task_duration, task_duration_type, task_priority, task_percent_complete,' .
  3818. ' task_hours_worked, task_order, task_project, task_milestone, task_access,' .
  3819. ' task_owner, project_name, project_color_identifier, task_dynamic');
  3820. $q->addJoin('projects', 'p', 'project_id = t.task_project', 'inner');
  3821. // don't add milestones if box is checked//////////////////////////////////////////////////////////
  3822. if ($showNoMilestones) {
  3823. $q->addWhere('task_milestone != 1');
  3824. }
  3825. if ($showMilestonesOnly) {
  3826. $q->addWhere('task_milestone = 1');
  3827. }
  3828. if ($ganttTaskFilter) {
  3829. $q->addWhere($where);
  3830. }
  3831. if ($project_id) {
  3832. $q->addWhere('task_project = ' . (int) $project_id);
  3833. }
  3834. switch ($f) {
  3835. case 'all':
  3836. $q->addWhere('task_status > -1');
  3837. break;
  3838. case 'myproj':
  3839. $q->addWhere('task_status > -1');
  3840. $q->addWhere('project_owner = ' . (int) $AppUI->user_id);
  3841. break;
  3842. case 'mycomp':
  3843. $q->addWhere('task_status > -1');
  3844. $q->addWhere('project_company = ' . (int) $AppUI->user_company);
  3845. break;
  3846. case 'myinact':
  3847. $q->innerJoin('user_tasks', 'ut', 'ut.task_id = t.task_id');
  3848. $q->addWhere('task_project = p.project_id');
  3849. $q->addWhere('ut.user_id = ' . (int) $AppUI->user_id);
  3850. break;
  3851. default:
  3852. $q->innerJoin('user_tasks', 'ut', 'ut.task_id = t.task_id');
  3853. $q->addWhere('task_status > -1');
  3854. $q->addWhere('task_project = p.project_id');
  3855. $q->addWhere('ut.user_id = ' . (int) $AppUI->user_id);
  3856. break;
  3857. }
  3858. $q->addOrder('t.task_start_date, t.task_end_date, t.task_priority');
  3859. // get any specifically denied tasks
  3860. $q = $task->setAllowedSQL($AppUI->user_id, $q);
  3861. $proTasks = $q->loadHashList('task_id');
  3862. return $proTasks;
  3863. }
  3864. /**
  3865. * @param $a
  3866. *
  3867. * @return array
  3868. */
  3869. function __extract_from_gantt_pdf($a)
  3870. {
  3871. $q = new w2p_Database_Query;
  3872. $q->addTable('tasks', 't');
  3873. $q->addJoin('user_tasks', 'u', 't.task_id = u.task_id');
  3874. $q->addQuery('ROUND(SUM(t.task_duration*u.perc_assignment/100),2) AS wh');
  3875. $q->addWhere('t.task_duration_type = 24');
  3876. $q->addWhere('t.task_id = ' . (int) $a['task_id']);
  3877. $wh = $q->loadResult();
  3878. return $wh;
  3879. }
  3880. /**
  3881. * @param $a
  3882. *
  3883. * @return array
  3884. */
  3885. function __extract_from_gantt_pdf2($a)
  3886. {
  3887. $q = new w2p_Database_Query;
  3888. $q->addTable('tasks', 't');
  3889. $q->addJoin('user_tasks', 'u', 't.task_id = u.task_id');
  3890. $q->addQuery('ROUND(SUM(t.task_duration*u.perc_assignment/100),2) AS wh');
  3891. $q->addWhere('t.task_duration_type = 1');
  3892. $q->addWhere('t.task_id = ' . (int) $a['task_id']);
  3893. $wh2 = $q->loadResult();
  3894. return $wh2;
  3895. }
  3896. /**
  3897. * @param $user_id
  3898. * @param $showArcProjs
  3899. * @param $showLowTasks
  3900. * @param $showHoldProjs
  3901. * @param $showDynTasks
  3902. * @param $showPinned
  3903. * @param $task
  3904. * @param $AppUI
  3905. *
  3906. * @return array
  3907. */
  3908. function __extract_from_gantt_pdf3($user_id, $showArcProjs, $showLowTasks, $showHoldProjs, $showDynTasks, $showPinned, $task, $AppUI)
  3909. {
  3910. $q = new w2p_Database_Query;
  3911. $q->addQuery('t.*');
  3912. $q->addQuery('project_name, project_id, project_color_identifier');
  3913. $q->addQuery('tp.task_pinned');
  3914. $q->addTable('tasks', 't');
  3915. $q->innerJoin('projects', 'pr', 'pr.project_id = t.task_project');
  3916. $q->leftJoin('user_tasks', 'ut', 'ut.task_id = t.task_id AND ut.user_id = ' . (int) $user_id);
  3917. $q->leftJoin('user_task_pin', 'tp', 'tp.task_id = t.task_id and tp.user_id = ' . (int) $user_id);
  3918. $q->addWhere('(t.task_percent_complete < 100 OR t.task_percent_complete IS NULL)');
  3919. $q->addWhere('t.task_status = 0');
  3920. if (!$showArcProjs) {
  3921. $q->addWhere('pr.project_active = 1');
  3922. if (($template_status = w2PgetConfig('template_projects_status_id')) != '') {
  3923. $q->addWhere('pr.project_status <> ' . (int) $template_status);
  3924. }
  3925. }
  3926. if (!$showLowTasks) {
  3927. $q->addWhere('task_priority >= 0');
  3928. }
  3929. if (!$showHoldProjs) {
  3930. $q->addWhere('project_active = 1');
  3931. }
  3932. if (!$showDynTasks) {
  3933. $q->addWhere('task_dynamic <> 1');
  3934. }
  3935. if ($showPinned) {
  3936. $q->addWhere('task_pinned = 1');
  3937. }
  3938. $q->addGroup('t.task_id');
  3939. $q->addOrder('t.task_end_date, t.task_priority DESC');
  3940. $q = $task->setAllowedSQL($AppUI->user_id, $q);
  3941. $proTasks = $q->loadHashList('task_id');
  3942. return $proTasks;
  3943. }
  3944. /**
  3945. * @param $project_id
  3946. * @param $f
  3947. * @param $AppUI
  3948. * @param $task
  3949. *
  3950. * @return array
  3951. */
  3952. function __extract_from_gantt_pdf4($project_id, $f, $AppUI, $task)
  3953. {
  3954. // pull tasks
  3955. $q = new w2p_Database_Query();
  3956. $q->addTable('tasks', 't');
  3957. $q->addQuery('t.task_id, task_parent, task_name, task_start_date, task_end_date,' .
  3958. ' task_duration, task_duration_type, task_priority, task_percent_complete,' .
  3959. ' task_hours_worked, task_order, task_project, task_milestone, task_access,' .
  3960. ' task_owner, project_name, project_color_identifier, task_dynamic');
  3961. $q->addJoin('projects', 'p', 'project_id = t.task_project', 'inner');
  3962. $q->addOrder('p.project_id, t.task_end_date');
  3963. if ($project_id) {
  3964. $q->addWhere('task_project = ' . (int) $project_id);
  3965. }
  3966. switch ($f) {
  3967. case 'all':
  3968. $q->addWhere('task_status > -1');
  3969. break;
  3970. case 'myproj':
  3971. $q->addWhere('task_status > -1');
  3972. $q->addWhere('project_owner = ' . (int) $AppUI->user_id);
  3973. break;
  3974. case 'mycomp':
  3975. $q->addWhere('task_status > -1');
  3976. $q->addWhere('project_company = ' . (int) $AppUI->user_company);
  3977. break;
  3978. case 'myinact':
  3979. $q->innerJoin('user_tasks', 'ut', 'ut.task_id = t.task_id');
  3980. $q->addWhere('ut.user_id = ' . $AppUI->user_id);
  3981. break;
  3982. default:
  3983. $q->innerJoin('user_tasks', 'ut', 'ut.task_id = t.task_id');
  3984. $q->addWhere('ut.user_id = ' . (int) $AppUI->user_id);
  3985. break;
  3986. }
  3987. $q = $task->setAllowedSQL($AppUI->user_id, $q);
  3988. $proTasks = $q->loadHashList('task_id');
  3989. return $proTasks;
  3990. }
  3991. /**
  3992. * @param $department
  3993. *
  3994. * @return array
  3995. */
  3996. function __extract_from_projects_gantt($department)
  3997. {
  3998. $q = new w2p_Database_Query;
  3999. $q->addTable('users');
  4000. $q->addQuery('user_id');
  4001. $q->addJoin('contacts', 'c', 'c.contact_id = user_contact', 'inner');
  4002. $q->addWhere('c.contact_department = ' . (int) $department);
  4003. $owner_ids = $q->loadColumn();
  4004. return $owner_ids;
  4005. }
  4006. /**
  4007. * @param $department
  4008. * @param $addPwOiD
  4009. * @param $project_type
  4010. * @param $owner
  4011. * @param $statusFilter
  4012. * @param $company_id
  4013. * @param $owner_ids
  4014. * @param $showInactive
  4015. * @param $AppUI
  4016. * @param $pjobj
  4017. *
  4018. * @return mixed
  4019. */
  4020. function __extract_from_projects_gantt2($department, $addPwOiD, $project_type, $owner, $statusFilter, $company_id, $owner_ids, $showInactive, $AppUI, $pjobj)
  4021. {
  4022. // pull valid projects and their percent complete information
  4023. $q = new w2p_Database_Query;
  4024. $q->addTable('projects', 'pr');
  4025. $q->addQuery('DISTINCT pr.project_id, project_color_identifier, project_name, project_start_date, project_end_date,
  4026. max(t1.task_end_date) AS project_actual_end_date, project_percent_complete,
  4027. project_status, project_active');
  4028. $q->addJoin('tasks', 't1', 'pr.project_id = t1.task_project');
  4029. $q->addJoin('companies', 'c1', 'pr.project_company = c1.company_id');
  4030. if ($department > 0 && !$addPwOiD) {
  4031. $q->addWhere('project_departments.department_id = ' . (int) $department);
  4032. }
  4033. if ($project_type > -1) {
  4034. $q->addWhere('pr.project_type = ' . (int) $project_type);
  4035. }
  4036. if ($owner > 0) {
  4037. $q->addWhere('pr.project_owner = ' . (int) $owner);
  4038. }
  4039. if ($statusFilter > -1) {
  4040. $q->addWhere('pr.project_status = ' . (int) $statusFilter);
  4041. }
  4042. if (!($department > 0) && $company_id > 0 && !$addPwOiD) {
  4043. $q->addWhere('pr.project_company = ' . (int) $company_id);
  4044. }
  4045. // Show Projects where the Project Owner is in the given department
  4046. if ($addPwOiD && !empty($owner_ids)) {
  4047. $q->addWhere('pr.project_owner IN (' . implode(',', $owner_ids) . ')');
  4048. }
  4049. if ($showInactive != '1') {
  4050. $q->addWhere('pr.project_active = 1');
  4051. if (($template_status = w2PgetConfig('template_projects_status_id')) != '') {
  4052. $q->addWhere('pr.project_status <> ' . $template_status);
  4053. }
  4054. }
  4055. $search_text = $AppUI->getState('projsearchtext') !== null ? $AppUI->getState('projsearchtext') : '';
  4056. if (mb_trim($search_text)) {
  4057. $q->addWhere('pr.project_name LIKE \'%' . $search_text . '%\' OR pr.project_description LIKE \'%' . $search_text . '%\'');
  4058. }
  4059. $q = $pjobj->setAllowedSQL($AppUI->user_id, $q, null, 'pr');
  4060. $q->addGroup('pr.project_id');
  4061. $q->addOrder('pr.project_name, task_end_date DESC');
  4062. $projects = $q->loadList();
  4063. return $projects;
  4064. }
  4065. /**
  4066. * @param $department
  4067. * @param $company_id
  4068. * @param $original_project_id
  4069. * @param $pjobj
  4070. * @param $AppUI
  4071. *
  4072. * @return array
  4073. */
  4074. function __extract_from_subprojects_gantt($department, $company_id, $original_project_id, $pjobj, $AppUI)
  4075. {
  4076. // pull valid projects and their percent complete information
  4077. // GJB: Note that we have to special case duration type 24 and this refers to the hours in a day, NOT 24 hours
  4078. $q = new w2p_Database_Query;
  4079. $q->addTable('projects', 'pr');
  4080. $q->addQuery('DISTINCT pr.project_id, project_color_identifier, project_name, project_start_date, project_end_date,
  4081. max(t1.task_end_date) AS project_actual_end_date, project_percent_complete, project_status, project_active');
  4082. $q->addJoin('tasks', 't1', 'pr.project_id = t1.task_project');
  4083. $q->addJoin('companies', 'c1', 'pr.project_company = c1.company_id');
  4084. if ($department > 0) {
  4085. $q->addWhere('project_departments.department_id = ' . (int) $department);
  4086. }
  4087. if (!($department > 0) && $company_id != 0) {
  4088. $q->addWhere('project_company = ' . (int) $company_id);
  4089. }
  4090. $q->addWhere('project_original_parent = ' . (int) $original_project_id);
  4091. $q = $pjobj->setAllowedSQL($AppUI->user_id, $q, null, 'pr');
  4092. $q->addGroup('pr.project_id');
  4093. $q->addOrder('project_start_date, project_end_date, project_name');
  4094. $projects = $q->loadHashList('project_id');
  4095. return $projects;
  4096. }
  4097. /**
  4098. * @param $original_project_id
  4099. * @param $task
  4100. * @param $AppUI
  4101. *
  4102. * @return array
  4103. */
  4104. function __extract_from_subprojects_gantt2($original_project_id, $task, $AppUI)
  4105. {
  4106. // insert tasks into Gantt Chart
  4107. // select for tasks for each project
  4108. // pull tasks
  4109. $q = new w2p_Database_Query;
  4110. $q->addTable('tasks', 't');
  4111. $q->addQuery('t.task_id, task_parent, task_name, task_start_date, task_end_date, task_duration, task_duration_type, task_priority, task_percent_complete, task_order, task_project, task_milestone, project_id, project_name, task_dynamic');
  4112. $q->addJoin('projects', 'p', 'project_id = t.task_project');
  4113. $q->addOrder('project_id, task_start_date');
  4114. $q->addWhere('project_original_parent = ' . (int) $original_project_id);
  4115. $q = $task->setAllowedSQL($AppUI->user_id, $q);
  4116. $proTasks = $q->loadHashList('task_id');
  4117. return $proTasks;
  4118. }
  4119. /**
  4120. * @param $AppUI
  4121. *
  4122. * @return array
  4123. */
  4124. function __extract_from_projectdesigner1($AppUI)
  4125. {
  4126. //Lets load the users panel viewing options
  4127. $q = new w2p_Database_Query;
  4128. $q->addTable('project_designer_options', 'pdo');
  4129. $q->addQuery('pdo.*');
  4130. $q->addWhere('pdo.pd_option_user = ' . (int) $AppUI->user_id);
  4131. $view_options = $q->loadList();
  4132. return $view_options;
  4133. }
  4134. /**
  4135. * @return array
  4136. */
  4137. function __extract_from_projectdesigner2()
  4138. {
  4139. $q = new w2p_Database_Query;
  4140. $q->addTable('projects');
  4141. $q->addQuery('projects.project_id, company_name');
  4142. $q->addJoin('companies', 'co', 'co.company_id = project_company');
  4143. $idx_companies = $q->loadHashList();
  4144. return $idx_companies;
  4145. }
  4146. /**
  4147. * @param $controller
  4148. */
  4149. function __extract_from_contact_controller($controller)
  4150. {
  4151. $updatekey = $controller->object->getUpdateKey();
  4152. $notifyasked = w2PgetParam($_POST, 'contact_updateask', 0);
  4153. if ($notifyasked && !strlen($updatekey)) {
  4154. $rnow = new w2p_Utilities_Date();
  4155. $controller->object->contact_updatekey = MD5($rnow->format(FMT_DATEISO));
  4156. $controller->object->contact_updateasked = $rnow->format(FMT_DATETIME_MYSQL);
  4157. $controller->object->contact_lastupdate = '';
  4158. $controller->object->store();
  4159. $controller->object->notify();
  4160. }
  4161. return $controller;
  4162. }
  4163. /**
  4164. * @param $row
  4165. *
  4166. * @return Array
  4167. */
  4168. function __extract_from_vw_usr($row)
  4169. {
  4170. $q = new w2p_Database_Query;
  4171. $q->addTable('user_access_log', 'ual');
  4172. $q->addQuery('user_access_log_id, ( unix_timestamp( \'' . $q->dbfnNowWithTZ() . '\' ) - unix_timestamp( date_time_in ) ) / 3600 as hours, ( unix_timestamp( \'' . $q->dbfnNowWithTZ() . '\' ) - unix_timestamp( date_time_last_action ) ) / 3600 as idle, if(isnull(date_time_out) or date_time_out =\'0000-00-00 00:00:00\',\'1\',\'0\') as online');
  4173. $q->addWhere('user_id = ' . (int) $row['user_id']);
  4174. $q->addOrder('user_access_log_id DESC');
  4175. $q->setLimit(1);
  4176. $user_logs = $q->loadList();
  4177. return $user_logs;
  4178. }
  4179. /**
  4180. * @param $module
  4181. * @param $mod_data
  4182. *
  4183. * @return Value
  4184. */
  4185. function __extract_from_vw_usr_perms($module, $mod_data)
  4186. {
  4187. $q = new w2p_Database_Query();
  4188. $q->addTable($module['permissions_item_table']);
  4189. $q->addQuery($module['permissions_item_label']);
  4190. $q->addWhere($module['permissions_item_field'] . '=' . $mod_data['value']);
  4191. $data = $q->loadResult();
  4192. return $data;
  4193. }
  4194. /**
  4195. * @param $orderby
  4196. *
  4197. * @return Array
  4198. */
  4199. function __extract_from_vw_usr_sessions($orderby)
  4200. {
  4201. $q = new w2p_Database_Query;
  4202. $q->addTable('sessions', 's');
  4203. $q->addQuery('DISTINCT(session_id), user_access_log_id, u.user_id, u.user_id as u_user_id,
  4204. user_username, contact_last_name, contact_display_name, contact_first_name,
  4205. company_name, contact_company, date_time_in, user_ip');
  4206. $q->addJoin('user_access_log', 'ual', 'session_user = user_access_log_id');
  4207. $q->addJoin('users', 'u', 'ual.user_id = u.user_id');
  4208. $q->addJoin('contacts', 'con', 'u.user_contact = contact_id');
  4209. $q->addJoin('companies', 'com', 'contact_company = company_id');
  4210. $q->addOrder($orderby);
  4211. $rows = $q->loadList();
  4212. return $rows;
  4213. }
  4214. /**
  4215. * @param $row
  4216. *
  4217. * @return array
  4218. */
  4219. function __extract_from_forums_view_messages($row)
  4220. {
  4221. $q = new w2p_Database_Query;
  4222. $q->addTable('forum_messages');
  4223. $q->addTable('users');
  4224. $q->addQuery('DISTINCT contact_first_name, contact_last_name, contact_display_name as contact_name, user_username, contact_email');
  4225. $q->addJoin('contacts', 'con', 'contact_id = user_contact', 'inner');
  4226. $q->addWhere('users.user_id = ' . (int) $row['message_editor']);
  4227. $editor = $q->loadList();
  4228. return $editor;
  4229. }
  4230. // Now we need to update the forum visits with the new messages so they don't show again.
  4231. /**
  4232. * @param $AppUI
  4233. * @param $forum_id
  4234. * @param $msg_id
  4235. * @param $date
  4236. */
  4237. function __extract_from_forums_view_messages2($AppUI, $forum_id, $msg_id, $date)
  4238. {
  4239. $q = new w2p_Database_Query;
  4240. $q->addTable('forum_visits');
  4241. $q->addInsert('visit_user', $AppUI->user_id);
  4242. $q->addInsert('visit_forum', $forum_id);
  4243. $q->addInsert('visit_message', $msg_id);
  4244. $q->addInsert('visit_date', $date->getDate());
  4245. $q->exec();
  4246. }
  4247. /**
  4248. * @param $AppUI
  4249. * @param $forum_id
  4250. * @param $f
  4251. * @param $orderby
  4252. * @param $orderdir
  4253. *
  4254. * @return Array
  4255. */
  4256. function __extract_from_forums_view_topics($AppUI, $forum_id, $f, $orderby, $orderdir)
  4257. {
  4258. //Pull All Messages
  4259. $q = new w2p_Database_Query;
  4260. $q->addTable('forum_messages', 'fm1');
  4261. $q->addQuery('fm1.*, u.*, fm1.message_title as message_name, fm1.message_forum as forum_id');
  4262. $q->addQuery('COUNT(distinct fm2.message_id) AS replies');
  4263. $q->addQuery('MAX(fm2.message_date) AS latest_reply');
  4264. $q->addQuery('user_username, contact_first_name, contact_last_name, contact_display_name as contact_name, watch_user');
  4265. $q->addQuery('count(distinct v1.visit_message) as reply_visits');
  4266. $q->addQuery('v1.visit_user');
  4267. $q->leftJoin('users', 'u', 'fm1.message_author = u.user_id');
  4268. $q->leftJoin('contacts', 'con', 'contact_id = user_contact');
  4269. $q->leftJoin('forum_messages', 'fm2', 'fm1.message_id = fm2.message_parent');
  4270. $q->leftJoin('forum_watch', 'fw', 'watch_user = ' . (int) $AppUI->user_id . ' AND watch_topic = fm1.message_id');
  4271. $q->leftJoin('forum_visits', 'v1', 'v1.visit_user = ' . (int) $AppUI->user_id . ' AND v1.visit_message = fm1.message_id');
  4272. $q->addWhere('fm1.message_forum = ' . (int) $forum_id);
  4273. $q->addWhere('fm1.message_parent < 1');
  4274. switch ($f) {
  4275. case 1:
  4276. $q->addWhere('watch_user IS NOT NULL');
  4277. break;
  4278. case 2:
  4279. $q->addWhere('(NOW() < DATE_ADD(fm2.message_date, INTERVAL 30 DAY) OR NOW() < DATE_ADD(fm1.message_date, INTERVAL 30 DAY))');
  4280. break;
  4281. }
  4282. $q->addGroup('fm1.message_id, fm1.message_parent');
  4283. $q->addOrder($orderby . ' ' . $orderdir);
  4284. $items = $q->loadList();
  4285. return $items;
  4286. }
  4287. /**
  4288. * @param $row
  4289. *
  4290. * @return Array
  4291. */
  4292. function __extract_from_tasks2($row)
  4293. {
  4294. $q = new w2p_Database_Query;
  4295. $q->addQuery('ut.user_id, u.user_username, ut.user_task_priority');
  4296. $q->addQuery('ut.perc_assignment');
  4297. $q->addQuery('contact_display_name AS assignee, contact_email');
  4298. $q->addTable('user_tasks', 'ut');
  4299. $q->addJoin('users', 'u', 'u.user_id = ut.user_id', 'inner');
  4300. $q->addJoin('contacts', 'c', 'u.user_contact = c.contact_id', 'inner');
  4301. $q->addWhere('ut.task_id = ' . (int) $row['task_id']);
  4302. $q->addOrder('perc_assignment desc, contact_first_name, contact_last_name');
  4303. $assigned_users = $q->loadList();
  4304. return $assigned_users;
  4305. }
  4306. /**
  4307. * @return array
  4308. */
  4309. function __extract_from_vw_actions()
  4310. {
  4311. $q = new w2p_Database_Query;
  4312. $q->addTable('projects');
  4313. $q->addQuery('projects.project_id, company_name');
  4314. $q->addJoin('companies', 'co', 'co.company_id = project_company');
  4315. return $q->loadHashList();
  4316. }
  4317. /**
  4318. * @param $f
  4319. * @param $q
  4320. * @param $user_id
  4321. * @param $task_id
  4322. * @param $AppUI
  4323. * @return string
  4324. */
  4325. function __extract_from_tasks3($f, $q, $user_id, $task_id, $AppUI)
  4326. {
  4327. $f = (($f) ? $f : '');
  4328. if ($task_id) {
  4329. //if we are on a task context make sure we show ALL the children tasks
  4330. $f = 'deepchildren';
  4331. }
  4332. switch ($f) {
  4333. case 'myfinished7days':
  4334. $q->addWhere('ut.user_id = ' . (int) $user_id);
  4335. case 'allfinished7days':
  4336. $q->addTable('user_tasks');
  4337. $q->addWhere('user_tasks.user_id = ' . (int) $user_id);
  4338. $q->addWhere('user_tasks.task_id = tasks.task_id');
  4339. $q->addWhere('task_percent_complete = 100');
  4340. //TODO: use date class to construct date.
  4341. $q->addWhere('task_end_date >= \'' . date('Y-m-d 00:00:00', mktime(0, 0, 0, date('m'), date('d') - 7, date('Y'))) . '\'');
  4342. break;
  4343. case 'children':
  4344. $q->addWhere('task_parent = ' . (int) $task_id);
  4345. $q->addWhere('tasks.task_id <> ' . $task_id);
  4346. break;
  4347. case 'deepchildren':
  4348. $taskobj = new CTask;
  4349. $taskobj->load((int) $task_id);
  4350. $deepchildren = $taskobj->getDeepChildren();
  4351. $q->addWhere('tasks.task_id IN (' . implode(',', $deepchildren) . ')');
  4352. $q->addWhere('tasks.task_id <> ' . $task_id);
  4353. break;
  4354. case 'myproj':
  4355. $q->addWhere('project_owner = ' . (int) $user_id);
  4356. break;
  4357. case 'mycomp':
  4358. if (!$AppUI->user_company) {
  4359. $AppUI->user_company = 0;
  4360. }
  4361. $q->addWhere('project_company = ' . (int) $AppUI->user_company);
  4362. break;
  4363. case 'myunfinished':
  4364. $q->addTable('user_tasks');
  4365. $q->addWhere('user_tasks.user_id = ' . (int) $user_id);
  4366. $q->addWhere('user_tasks.task_id = tasks.task_id');
  4367. $q->addWhere('(task_percent_complete < 100 OR task_end_date = \'\')');
  4368. break;
  4369. case 'allunfinished':
  4370. $q->addWhere('(task_percent_complete < 100 OR task_end_date = \'\')');
  4371. break;
  4372. case 'unassigned':
  4373. $q->leftJoin('user_tasks', 'ut_empty', 'tasks.task_id = ut_empty.task_id');
  4374. $q->addWhere('ut_empty.task_id IS NULL');
  4375. break;
  4376. case 'taskcreated':
  4377. $q->addWhere('task_creator = ' . (int) $user_id);
  4378. break;
  4379. case 'taskowned':
  4380. $q->addWhere('task_owner = ' . (int) $user_id);
  4381. break;
  4382. case 'all':
  4383. //break;
  4384. default:
  4385. if ($user_id) {
  4386. $q->addTable('user_tasks');
  4387. $q->addWhere('user_tasks.user_id = ' . (int) $user_id);
  4388. $q->addWhere('user_tasks.task_id = tasks.task_id');
  4389. }
  4390. break;
  4391. }
  4392. return $q;
  4393. }
  4394. /**
  4395. * @param $min_view
  4396. * @param $currentTabId
  4397. * @param $project_id
  4398. * @param $currentTabName
  4399. * @param $AppUI
  4400. * @return int
  4401. */
  4402. function __extract_from_tasks($min_view, $currentTabId, $project_id, $currentTabName, $AppUI)
  4403. {
  4404. //TODO: This whole structure is hard-coded based on the TaskStatus SelectList.
  4405. $task_status = 0;
  4406. if ($min_view && isset($_GET['task_status'])) {
  4407. $task_status = (int)w2PgetParam($_GET, 'task_status', null);
  4408. return $task_status;
  4409. } elseif ($currentTabId == 1 && $project_id) {
  4410. $task_status = -1;
  4411. return $task_status;
  4412. } elseif ($currentTabId > 1 && $project_id) {
  4413. $task_status = $currentTabId - 1;
  4414. return $task_status;
  4415. } elseif (!$currentTabName) {
  4416. // If we aren't tabbed we are in the tasks list.
  4417. $task_status = (int)$AppUI->getState('inactive');
  4418. return $task_status;
  4419. }
  4420. return $task_status;
  4421. }
  4422. /**
  4423. * @param $where_list
  4424. * @param $project_id
  4425. * @param $task_id
  4426. * @return Array
  4427. */
  4428. function __extract_from_tasks4($where_list, $project_id, $task_id)
  4429. {
  4430. $q = new w2p_Database_Query;
  4431. $q->addTable('projects', 'p');
  4432. $q->addQuery('company_name, p.project_id, project_color_identifier, project_name, project_percent_complete, project_task_count');
  4433. $q->addJoin('companies', 'com', 'company_id = project_company', 'inner');
  4434. $q->addJoin('tasks', 't1', 'p.project_id = t1.task_project', 'inner');
  4435. $q->leftJoin('project_departments', 'project_departments', 'p.project_id = project_departments.project_id OR project_departments.project_id IS NULL');
  4436. $q->leftJoin('departments', 'departments', 'departments.dept_id = project_departments.department_id OR dept_id IS NULL');
  4437. $q->addWhere($where_list . (($where_list) ? ' AND ' : '') . 't1.task_id = t1.task_parent');
  4438. $q->addGroup('p.project_id');
  4439. if (!$project_id && !$task_id) {
  4440. $q->addOrder('project_name');
  4441. }
  4442. if ($project_id > 0) {
  4443. $q->addWhere('p.project_id = ' . $project_id);
  4444. }
  4445. $projects = $q->loadList(-1, 'project_id');
  4446. return $projects;
  4447. }
  4448. /**
  4449. * @param $q
  4450. * @param $subquery
  4451. */
  4452. function __extract_from_tasks5($q, $subquery)
  4453. {
  4454. $q->addQuery('tasks.task_id, task_parent, task_name');
  4455. $q->addQuery('task_start_date, task_end_date, task_dynamic');
  4456. $q->addQuery('task_pinned, pin.user_id as pin_user');
  4457. $q->addQuery('ut.user_task_priority');
  4458. $q->addQuery('task_priority, task_percent_complete');
  4459. $q->addQuery('task_duration, task_duration_type');
  4460. $q->addQuery('task_project, task_represents_project');
  4461. $q->addQuery('task_description, task_owner, task_status');
  4462. $q->addQuery('usernames.user_username, usernames.user_id');
  4463. $q->addQuery('assignees.user_username as assignee_username');
  4464. $q->addQuery('count(distinct assignees.user_id) as assignee_count');
  4465. $q->addQuery('co.contact_first_name, co.contact_last_name');
  4466. $q->addQuery('contact_display_name AS contact_name');
  4467. $q->addQuery('contact_display_name AS owner');
  4468. $q->addQuery('task_milestone');
  4469. $q->addQuery('count(distinct f.file_task) as file_count');
  4470. $q->addQuery('tlog.task_log_problem');
  4471. $q->addQuery('task_access');
  4472. $q->addQuery('(' . $subquery . ') AS task_nr_of_children');
  4473. $q->addTable('tasks');
  4474. return $q;
  4475. }
  4476. /**
  4477. * @param $AppUI
  4478. * @param $task_id
  4479. */
  4480. function __extract_from_tasks_pinning($AppUI, $task_id)
  4481. {
  4482. if (isset($_GET['pin'])) {
  4483. $pin = (int)w2PgetParam($_GET, 'pin', 0);
  4484. $task = new CTask();
  4485. // load the record data
  4486. if (1 == $pin) {
  4487. $result = $task->pinTask($AppUI->user_id, $task_id);
  4488. }
  4489. if (-1 == $pin) {
  4490. $result = $task->unpinTask($AppUI->user_id, $task_id);
  4491. }
  4492. if (!$result) {
  4493. $AppUI->setMsg('Pinning ', UI_MSG_ERROR, true);
  4494. }
  4495. $task->load($task_id);
  4496. $AppUI->redirect('m=projects&a=view&project_id='.$task->task_project, -1);
  4497. }
  4498. }
  4499. /**
  4500. * Check if start date exists, if not try giving it the end date. If the end date does not exist then set it for
  4501. * today. This avoids jpgraphs internal errors that render the gantt completely useless
  4502. *
  4503. * @param $row
  4504. * @return array
  4505. */
  4506. function __extract_from_projects_gantt3($row)
  4507. {
  4508. if ($row['task_start_date'] == '0000-00-00 00:00:00') {
  4509. if ($row['task_end_date'] == '0000-00-00 00:00:00') {
  4510. $todaydate = new w2p_Utilities_Date();
  4511. $row['task_start_date'] = $todaydate->format(FMT_TIMESTAMP_DATE);
  4512. } else {
  4513. $row['task_start_date'] = $row['task_end_date'];
  4514. }
  4515. }
  4516. return $row['task_start_date'];
  4517. }
  4518. /**
  4519. * Check if end date exists, if not try giving it the start date. If the start date does not exist then set it for
  4520. * today. This avoids jpgraphs internal errors that render the gantt completely useless
  4521. *
  4522. * @param $row
  4523. * @return array
  4524. */
  4525. function __extract_from_projects_gantt4($row)
  4526. {
  4527. if ($row['task_end_date'] == '0000-00-00 00:00:00') {
  4528. if ($row['task_duration']) {
  4529. $date = new w2p_Utilities_Date($row['task_start_date']);
  4530. $date->addDuration($row['task_duration'], $row['task_duration_type']);
  4531. } else {
  4532. $date = new w2p_Utilities_Date();
  4533. }
  4534. $row['task_end_date'] = $date->format(FMT_TIMESTAMP_DATE);
  4535. }
  4536. return $row['task_end_date'];
  4537. }
  4538. /**
  4539. * @param $s
  4540. * @param $style
  4541. * @param $row
  4542. * @param $editor
  4543. * @param $AppUI
  4544. * @param $bbparser
  4545. * @return array
  4546. */
  4547. function __extract_from_view_messages1($s, $style, $row, $editor, $AppUI, $bbparser)
  4548. {
  4549. $s .= "<tr>";
  4550. $s .= '<td valign="top" style="' . $style . '" >';
  4551. $s .= '<a href="mailto:' . $row['contact_email'] . '">';
  4552. $s .= $row['contact_name'] . '</a>';
  4553. if (sizeof($editor) > 0) {
  4554. $s .= '<br/>&nbsp;<br/>' . $AppUI->_('last edited by');
  4555. $s .= ':<br/><a href="mailto:' . $editor[0]['contact_email'] . '">';
  4556. $s .= '<font size="1">' . $editor[0]['contact_name'] . '</font></a>';
  4557. }
  4558. $s .= '<a name="' . $row['message_id'] . '" href="javascript: void(0);" onclick="toggle(' . $row['message_id'] . ')">';
  4559. $s .= '<span size="2"><strong>' . $row['message_title'] . '</strong></span></a>';
  4560. $s .= '<div class="message" id="' . $row['message_id'] . '" style="display: none">';
  4561. $row['message_body'] = $bbparser->qparse($row['message_body']);
  4562. $s .= $row['message_body'];
  4563. $s .= '</div></td>';
  4564. $s .= '</tr>';
  4565. return $s;
  4566. }
  4567. /**
  4568. * @param $s
  4569. * @param $style
  4570. * @param $AppUI
  4571. * @param $row
  4572. * @param $df
  4573. * @param $tf
  4574. * @param $editor
  4575. * @param $side
  4576. * @param $bbparser
  4577. * @param $first
  4578. * @param $messages
  4579. * @return array
  4580. */
  4581. function __extract_from_view_messages3($s, $style, $AppUI, $row, $df, $tf, $editor, $side, $bbparser, $first, $messages)
  4582. {
  4583. $s .= '<tr>';
  4584. $s .= '<td valign="top" style="' . $style . '">';
  4585. $s .= $AppUI->formatTZAwareTime($row['message_date'], $df . ' ' . $tf) . ' - ';
  4586. $s .= '<a href="mailto:' . $row['contact_email'] . '">' . $row['contact_name'] . '</a>';
  4587. $s .= '<br />';
  4588. if (sizeof($editor) > 0) {
  4589. $s .= '<br/>&nbsp;<br/>' . $AppUI->_('last edited by');
  4590. $s .= ':<br/><a href="mailto:' . $editor[0]['contact_email'] . '">';
  4591. $s .= '<font size="1">' . $editor[0]['contact_name'] . '</font></a>';
  4592. }
  4593. $s .= '<a href="javascript: void(0);" onclick="toggle(' . $row['message_id'] . ')">';
  4594. $s .= '<span size="2"><strong>' . $row['message_title'] . '</strong></span></a>';
  4595. $side .= '<div class="message" id="' . $row['message_id'] . '" style="display: none">';
  4596. $side .= $row['message_body'];
  4597. $side .= '</div>';
  4598. $row['message_body'] = $bbparser->qparse($row['message_body']);
  4599. $s .= '</td>';
  4600. if ($first) {
  4601. $s .= '<td rowspan="' . count($messages) . '" valign="top">';
  4602. echo $s;
  4603. $s = '';
  4604. }
  4605. $s .= '</tr>';
  4606. return array($s, $side);
  4607. }
  4608. /**
  4609. * @param $s
  4610. * @param $style
  4611. * @param $row
  4612. * @param $hideEmail
  4613. * @param $editor
  4614. * @param $AppUI
  4615. * @param $new_messages
  4616. * @param $bbparser
  4617. * @param $m
  4618. * @param $df
  4619. * @param $tf
  4620. * @param $canEdit
  4621. * @param $canAdminEdit
  4622. * @param $canDelete
  4623. * @return array
  4624. */
  4625. function __extract_from_view_messages4($s, $style, $row, $hideEmail, $editor, $AppUI, $new_messages, $bbparser, $m, $df, $tf, $canEdit, $canAdminEdit, $canDelete)
  4626. {
  4627. $s .= '<tr>';
  4628. $s .= '<td valign="top" style="' . $style . '" nowrap="nowrap">';
  4629. $s .= '<a href="?m=users&a=view&user_id=' . $row['message_author'] . '">';
  4630. $s .= $row['contact_name'];
  4631. $s .= '</a>';
  4632. if (!$hideEmail) {
  4633. $s .= '&nbsp;';
  4634. $s .= '<a href="mailto:' . $row['contact_email'] . '">';
  4635. $s .= '<img src="' . w2PfindImage('email.gif') . '" alt="email" />';
  4636. $s .= '</a>';
  4637. }
  4638. if (sizeof($editor) > 0) {
  4639. $s .= '<br/>&nbsp;<br/>' . $AppUI->_('last edited by');
  4640. $s .= ':<br/>';
  4641. if (!$hideEmail) {
  4642. $s .= '<a href="mailto:' . $editor[0]['contact_email'] . '">';
  4643. }
  4644. $s .= $editor[0]['contact_name'];
  4645. if (!$hideEmail) {
  4646. $s .= '</a>';
  4647. }
  4648. }
  4649. if ($row['visit_user'] != $AppUI->user_id) {
  4650. $s .= '<br />&nbsp;' . w2PshowImage('icons/stock_new_small.png');
  4651. $new_messages[] = $row['message_id'];
  4652. }
  4653. $s .= '</td>';
  4654. $s .= '<td valign="top" style="' . $style . '">';
  4655. $s .= '<strong>' . $row['message_title'] . '</strong><hr size=1>';
  4656. $row['message_body'] = $bbparser->qparse($row['message_body']);
  4657. $row['message_body'] = nl2br($row['message_body']);
  4658. $s .= $row['message_body'];
  4659. $s .= '</td>';
  4660. $s .= '</tr><tr>';
  4661. $s .= '<td valign="top" style="' . $style . '" nowrap="nowrap">';
  4662. $s .= '<img src="' . w2PfindImage('icons/posticon.gif', $m) . '" alt="date posted" />' . $AppUI->formatTZAwareTime($row['message_date'], $df . ' ' . $tf) . '</td>';
  4663. $s .= '<td valign="top" align="right" style="' . $style . '">';
  4664. // in some weird permission cases
  4665. // it can happen that the table gets opened but never closed,
  4666. // or the other way around, thus breaking the layout
  4667. // introducing these variables to help us out with proper
  4668. // table tag opening and closing.
  4669. $tableOpened = false;
  4670. $tableClosed = false;
  4671. //the following users are allowed to edit/delete a forum message: 1. the forum creator 2. a superuser with read-write access to 'all' 3. the message author
  4672. if ($canEdit || $AppUI->user_id == $row['forum_moderated'] || $AppUI->user_id == $row['message_author'] || $canAdminEdit) {
  4673. $tableOpened = true;
  4674. $s .= '<table cellspacing="0" cellpadding="0" border="0"><tr>';
  4675. // edit message
  4676. $s .= '<td><a href="./index.php?m=forums&a=viewer&post_message=1&forum_id=' . $row['message_forum'] . '&message_parent=' . $row['message_parent'] . '&message_id=' . $row["message_id"] . '" title="' . $AppUI->_('Edit') . ' ' . $AppUI->_('Message') . '">';
  4677. $s .= w2PshowImage('icons/stock_edit-16.png', '16', '16');
  4678. $s .= '</td>';
  4679. }
  4680. if ($canDelete || $AppUI->user_id == $row['forum_moderated'] || $AppUI->user_id == $row['message_author'] || $canAdminEdit) {
  4681. $tableClosed = true;
  4682. if (!$tableOpened) {
  4683. $s .= '<table cellspacing="0" cellpadding="0" border="0"><tr>';
  4684. }
  4685. // delete message
  4686. $s .= '<td><a href="javascript:delIt(' . $row['message_id'] . ')" title="' . $AppUI->_('delete') . '">';
  4687. $s .= w2PshowImage('icons/stock_delete-16.png', '16', '16');
  4688. $s .= '</a>';
  4689. $s .= '</td></tr></table>';
  4690. }
  4691. if ($tableOpened and !$tableClosed) {
  4692. $s .= '</tr></table>';
  4693. }
  4694. $s .= '</td>';
  4695. $s .= '</tr>';
  4696. return array($s, $new_messages);
  4697. }