public function getAllTasksForPeriod($start_date, $end_date, $company_id = 0, $user_id = null)
 {
     global $AppUI;
     $q = new w2p_Database_Query();
     // convert to default db time stamp
     $db_start = $start_date->format(FMT_DATETIME_MYSQL);
     $db_end = $end_date->format(FMT_DATETIME_MYSQL);
     // Allow for possible passing of user_id 0 to stop user filtering
     if (!isset($user_id)) {
         $user_id = $AppUI->user_id;
     }
     // check permissions on projects
     $proj = new CProject();
     $task_filter_where = $proj->getAllowedSQL($AppUI->user_id, 't.task_project');
     // exclude read denied projects
     $deny = $proj->getDeniedRecords($AppUI->user_id);
     // check permissions on tasks
     $obj = new CTask();
     $allow = $obj->getAllowedSQL($AppUI->user_id, 't.task_id');
     $q->addTable('tasks', 't');
     if ($user_id) {
         $q->innerJoin('user_tasks', 'ut', 't.task_id=ut.task_id');
     }
     $q->innerJoin('projects', 'projects', 't.task_project = projects.project_id');
     $q->innerJoin('companies', 'companies', 'projects.project_company = companies.company_id');
     $q->leftJoin('project_departments', '', 'projects.project_id = project_departments.project_id');
     $q->leftJoin('departments', '', 'departments.dept_id = project_departments.department_id');
     $q->addQuery('DISTINCT t.task_id, t.task_name, t.task_start_date, t.task_end_date, t.task_percent_complete, t.task_duration' . ', t.task_duration_type, projects.project_color_identifier AS color, projects.project_name, t.task_milestone, task_description, task_type, company_name, task_access, task_owner');
     $q->addWhere('task_status > -1' . ' AND (task_start_date <= \'' . $db_end . '\'  AND t.task_percent_complete<100  OR task_end_date = \'0000-00-00 00:00:00\' OR task_end_date = NULL )');
     $q->addWhere('project_active = 1');
     if (($template_status = w2PgetConfig('template_projects_status_id')) != '') {
         $q->addWhere('project_status <> ' . $template_status);
     }
     if ($user_id) {
         $q->addWhere('ut.user_id = ' . (int) $user_id);
     }
     if ($company_id) {
         $q->addWhere('projects.project_company = ' . (int) $company_id);
     }
     if (count($task_filter_where) > 0) {
         $q->addWhere('(' . implode(' AND ', $task_filter_where) . ')');
     }
     if (count($deny) > 0) {
         $q->addWhere('(t.task_project NOT IN (' . implode(', ', $deny) . '))');
     }
     if (count($allow) > 0) {
         $q->addWhere('(' . implode(' AND ', $allow) . ')');
     }
     $q->addOrder('t.task_start_date');
     // assemble query
     $tasks = $q->loadList(-1, 'task_id');
     // check tasks access
     $result = array();
     foreach ($tasks as $key => $row) {
         $obj->load($row['task_id']);
         $canAccess = $obj->canAccess();
         if (!$canAccess) {
             continue;
         }
         $result[$key] = $row;
     }
     // execute and return
     return $result;
 }
/**
 * Used to check if a user has task_access to see the task in task list context
 * (This function was optimized to try to use the DB the least possible)
 * TODO:  Remove for v4.0 - caseydk 20 September 2012
 *
 * @param mixed $task_id
 * @param mixed $task_access
 * @param mixed $task_owner
 * @return true if user has task access to it, or false if he doesn't
 *
 * @deprecated
 */
function canTaskAccess($task_id)
{
    trigger_error("canTaskAccess has been deprecated in v3.0 and will be removed by v4.0. Please use CTask->canAccess() instead.", E_USER_NOTICE);
    global $AppUI;
    $task = new CTask();
    $task->load($task_id);
    return $task->canAccess($AppUI->user_id);
}
예제 #3
0
function showtask(&$a, $level = 0, $is_opened = true, $today_view = false, $hideOpenCloseLink = false, $allowRepeat = false)
{
    global $AppUI, $done, $query_string, $durnTypes, $userAlloc, $showEditCheckbox;
    global $tasks_opened, $tasks_closed, $user_id;
    $tasks_closed = $tasks_closed ? $tasks_closed : array();
    $tasks_opened = $tasks_opened ? $tasks_opened : array();
    $done = $done ? $done : array();
    $now = new CDate();
    $df = $AppUI->getPref('SHDATEFORMAT');
    $df .= ' ' . $AppUI->getPref('TIMEFORMAT');
    $show_all_assignees = dPgetConfig('show_all_task_assignees', false);
    if (!isset($done[$a['task_id']])) {
        $done[$a['task_id']] = 1;
    } else {
        if (!$allowRepeat) {
            //by default, we shouldn't allow repeat displays of the same task
            return;
        }
    }
    $task_obj = new CTask();
    $task_obj->peek($a['task_id']);
    if (!$task_obj->canAccess($user_id ? $user_id : $AppUI->user_id)) {
        //don't show tasks that we can't access
        return;
    }
    if ($is_opened) {
        openClosedTask($a);
    } else {
        closeOpenedTask($a);
    }
    $start_date = intval($a['task_start_date']) ? new CDate($a['task_start_date']) : null;
    $end_date = intval($a['task_end_date']) ? new CDate($a['task_end_date']) : null;
    $last_update = isset($a['last_update']) && intval($a['last_update']) ? new CDate($a['last_update']) : null;
    // prepare coloured highlight of task time information
    $style = '';
    if ($start_date) {
        if ($now->after($start_date) && $a['task_percent_complete'] == 0) {
            $style = 'background-color:#ffeebb';
        } else {
            if ($now->after($start_date) && $a['task_percent_complete'] < 100) {
                $style = 'background-color:#e6eedd';
            }
        }
        if (!empty($end_date) && $now->after($end_date)) {
            $style = 'background-color:#cc6666;color:#ffffff';
        }
        if (!$end_date) {
            /*
             ** end date calc has been moved to calcEndByStartAndDuration()-function
             ** called from array_csort and tasks.php 
             ** perhaps this fallback if-clause could be deleted in the future, 
             ** didn't want to remove it shortly before the 2.0.2
             */
            $end_date = new CDate('0000-00-00 00:00:00');
        }
        if ($a['task_percent_complete'] == 100) {
            $style = 'background-color:#aaddaa; color:#00000';
        }
        $days = $end_date->dateDiff($now);
    }
    $s = "\n<tr>";
    // edit icon
    $s .= "\n\t<td>";
    $canEdit = getPermission('tasks', 'edit', $a['task_id']);
    $canViewLog = getPermission('task_log', 'view', $a['task_id']);
    if ($canEdit) {
        $s .= "\n\t\t" . '<a href="?m=tasks&amp;a=addedit&amp;task_id=' . $a['task_id'] . '">' . "\n\t\t\t" . '<img src="./images/icons/pencil.gif" alt="' . $AppUI->_('Edit Task') . '" border="0" width="12" height="12" />' . "\n\t\t</a>";
    }
    $s .= "\n\t</td>";
    // pinned
    $pin_prefix = $a['task_pinned'] ? '' : 'un';
    $s .= "\n\t<td>\n\t\t" . '<a href="?m=tasks&amp;pin=' . ($a['task_pinned'] ? 0 : 1) . '&task_id=' . $a['task_id'] . '">' . "\n\t\t\t" . '<img src="./images/icons/' . $pin_prefix . 'pin.gif" alt="' . $AppUI->_($pin_prefix . 'pin Task') . '" border="0" width="12" height="12" />' . "\n\t\t</a>\n\t</td>";
    // New Log
    $s .= "\n\t" . '<td align="center">';
    if ($canViewLog && $a['task_dynamic'] != 1) {
        $s .= '<a href="?m=tasks&amp;a=view&amp;task_id=' . $a['task_id'] . '&tab=1">' . $AppUI->_('Log') . '</a>';
    } else {
        $s .= $AppUI->_('-');
    }
    $s .= '</td>';
    // percent complete and priority
    $s .= "\n\t" . '<td align="right">' . intval($a['task_percent_complete']) . '%</td>' . "\n\t" . '<td align="center" nowrap="nowrap">';
    if (@$a['task_log_problem'] > 0) {
        $s .= '<a href="?m=tasks&amp;a=view&amp;task_id=' . $a['task_id'] . '&amp;tab=0&amp;problem=1">' . dPshowImage('./images/icons/dialog-warning5.png', 16, 16, 'Problem', 'Problem!') . '</a>';
    } else {
        if ($a['task_priority'] != 0) {
            $s .= "\n\t\t" . dPshowImage('./images/icons/priority' . ($a['task_priority'] > 0 ? '+' : '-') . abs($a['task_priority']) . '.gif', 13, 16, '', '');
        }
    }
    $s .= (@$a['file_count'] > 0 ? '<img src="./images/clip.png" alt="F" />' : '') . '</td>';
    // dots
    $s .= '<td width="' . ($today_view ? '50%' : '90%') . '">';
    //level
    if ($level == -1) {
        $s .= '...';
    }
    for ($y = 0; $y < $level; $y++) {
        $s .= '<img src="' . ($y + 1 == $level ? './images/corner-dots.gif' : './images/shim.gif') . '" width="16" height="12" border="0" alt="" />';
    }
    // name link
    /*
    $alt = ((mb_strlen($a['task_description']) > 80) 
    		? (mb_substr($a['task_description'], 0, 80) . '...') : $a['task_description']);
    // instead of the statement below
    $alt = str_replace('"', '&quot;', $alt);
    $alt = htmlspecialchars($alt);
    $alt = str_replace("\r", ' ', $alt);
    $alt = str_replace("\n", ' ', $alt);
    */
    $alt = !empty($a['task_description']) ? 'onmouseover="javascript:return overlib(' . "'" . htmlspecialchars('<div><p>' . str_replace(array("\r\n", "\n", "\r"), '</p><p>', addslashes($a['task_description'])), ENT_QUOTES) . '</p></div>' . "', CAPTION, '" . $AppUI->_('Description') . "'" . ', CENTER);" onmouseout="nd();"' : ' ';
    if ($a['task_milestone'] > 0) {
        $s .= '&nbsp;<a href="./index.php?m=tasks&amp;a=view&amp;task_id=' . $a['task_id'] . '" ' . $alt . '>' . '<b>' . $a['task_name'] . '</b></a>' . '<img src="./images/icons/milestone.gif" border="0" alt="Milestone" /></td>';
    } else {
        if ($a['task_dynamic'] == 1 || count($task_obj->getChildren())) {
            if (!($today_view || $hideOpenCloseLink)) {
                $s .= '<a href="index.php' . $query_string . ($is_opened ? '&close_task_id=' . $a['task_id'] . '"><img src="images/icons/collapse.gif" align="center"' : '&open_task_id=' . $a['task_id'] . '"><img src="images/icons/expand.gif"') . ' border="0" alt="" /></a>';
            }
            $s .= '&nbsp;<a href="./index.php?m=tasks&amp;a=view&amp;task_id=' . $a['task_id'] . '" ' . $alt . '>' . ($a['task_dynamic'] == 1 ? '<b><i>' : '') . $a['task_name'] . ($a['task_dynamic'] == 1 ? '</i></b>' : '') . '</a></td>';
        } else {
            $s .= '&nbsp;<a href="./index.php?m=tasks&amp;a=view&amp;task_id=' . $a['task_id'] . '" ' . $alt . '>' . $a['task_name'] . '</a></td>';
        }
    }
    if ($today_view) {
        // Show the project name
        $s .= '<td width="50%"><a href="?m=projects&amp;a=view&amp;project_id=' . $a['task_project'] . '">' . '<span style="padding:2px;background-color:#' . $a['project_color_identifier'] . ';color:' . bestColor($a['project_color_identifier']) . '">' . $a['project_name'] . '</span>' . '</a></td>';
    }
    // task owner
    if (!$today_view) {
        $s .= '<td nowrap="nowrap" align="center">' . '<a href="?m=admin&amp;a=viewuser&amp;user_id=' . $a['user_id'] . '">' . $a['user_username'] . '</a>' . '</td>';
    }
    // $s .= '<td nowrap="nowrap" align="center">' . $a['user_username'] . '</td>';
    if (isset($a['task_assigned_users']) && ($assigned_users = $a['task_assigned_users'])) {
        $a_u_tmp_array = array();
        if ($show_all_assignees) {
            $s .= '<td align="center">';
            foreach ($assigned_users as $val) {
                /*
                $a_u_tmp_array[] = ('<a href="mailto:' . $val['user_email'] . '">' 
                					. $val['user_username'] . '</a>'); 
                */
                $a_u_tmp_array[] = '<a href="?m=admin&amp;a=viewuser&amp;user_id=' . $val['user_id'] . '"' . 'title="' . $AppUI->_('Extent of Assignment') . ':' . $userAlloc[$val['user_id']]['charge'] . '%; ' . $AppUI->_('Free Capacity') . ':' . $userAlloc[$val['user_id']]['freeCapacity'] . '%' . '">' . $val['user_username'] . ' (' . $val['perc_assignment'] . '%)</a>';
            }
            $s .= join(', ', $a_u_tmp_array) . '</td>';
        } else {
            $s .= '<td align="center" nowrap="nowrap">' . '<a href="?m=admin&amp;a=viewuser&amp;user_id=' . $assigned_users[0]['user_id'] . '" title="' . $AppUI->_('Extent of Assignment') . ':' . $userAlloc[$assigned_users[0]['user_id']]['charge'] . '%; ' . $AppUI->_('Free Capacity') . ':' . $userAlloc[$assigned_users[0]['user_id']]['freeCapacity'] . '%">' . $assigned_users[0]['user_username'] . ' (' . $assigned_users[0]['perc_assignment'] . '%)</a>';
            if ($a['assignee_count'] > 1) {
                $s .= ' <a href="javascript: void(0);" onclick="javascript:toggle_users(' . "'users_" . $a['task_id'] . "'" . ');" title="' . join(', ', $a_u_tmp_array) . '">(+' . ($a['assignee_count'] - 1) . ')</a>' . '<span style="display: none" id="users_' . $a['task_id'] . '">';
                $a_u_tmp_array[] = $assigned_users[0]['user_username'];
                for ($i = 1, $xi = count($assigned_users); $i < $xi; $i++) {
                    $a_u_tmp_array[] = $assigned_users[$i]['user_username'];
                    $s .= '<br /><a href="?m=admin&amp;a=viewuser&amp;user_id=' . $assigned_users[$i]['user_id'] . '" title="' . $AppUI->_('Extent of Assignment') . ':' . $userAlloc[$assigned_users[$i]['user_id']]['charge'] . '%; ' . $AppUI->_('Free Capacity') . ':' . $userAlloc[$assigned_users[$i]['user_id']]['freeCapacity'] . '%">' . $assigned_users[$i]['user_username'] . ' (' . $assigned_users[$i]['perc_assignment'] . '%)</a>';
                }
                $s .= '</span>';
            }
            $s .= '</td>';
        }
    } else {
        if (!$today_view) {
            // No users asigned to task
            $s .= '<td align="center">-</td>';
        }
    }
    // duration or milestone
    $s .= '<td nowrap="nowrap" align="center" style="' . $style . '">' . ($start_date ? $start_date->format($df) : '-') . '</td>' . '<td align="center" nowrap="nowrap" style="' . $style . '">' . $a['task_duration'] . ' ' . $AppUI->_($durnTypes[$a['task_duration_type']]) . '</td>' . '<td nowrap="nowrap" align="center" style="' . $style . '">' . ($end_date ? $end_date->format($df) : '-') . '</td>';
    if ($today_view) {
        $s .= '<td nowrap="nowrap" align="center" style="' . $style . '">' . $a['task_due_in'] . '</td>';
    } else {
        if ($AppUI->isActiveModule('history') && getPermission('history', 'view')) {
            $s .= '<td nowrap="nowrap" align="center" style="' . $style . '">' . ($last_update ? $last_update->format($df) : '-') . '</td>';
        }
    }
    // Assignment checkbox
    if ($showEditCheckbox) {
        $s .= "\n\t" . '<td align="center">' . '<input type="checkbox" name="selected_task[' . $a['task_id'] . ']" value="' . $a['task_id'] . '"/></td>';
    }
    $s .= '</tr>';
    echo $s;
}
예제 #4
0
} else {
    //do we have access on this project?
    $canEdit = getPermission('projects', 'view', $task_project);
    //And do we have add permission to tasks?
    if ($canEdit) {
        $canEdit = getPermission('tasks', 'add');
    }
}
if (!$canEdit) {
    $AppUI->redirect('m=public&a=access_denied&err=noedit');
}
//check permissions for the associated project
$canReadProject = getPermission('projects', 'view', $obj->task_project);
$durnTypes = dPgetSysVal('TaskDurationType');
//check the document access (public, participant, private)
if (!$obj->canAccess($AppUI->user_id)) {
    $AppUI->redirect('m=public&a=access_denied&err=noaccess');
}
//pull the related project
$project = new CProject();
$project->load($task_project);
//Pull all users
$perms =& $AppUI->acl();
$users = $perms->getPermittedUsers('tasks');
function getSpaces($amount)
{
    return $amount == 0 ? '' : str_repeat('&nbsp;', $amount);
}
function constructTaskTree($task_data, $depth = 0)
{
    global $projTasks, $all_tasks, $parents, $task_parent_options, $task_parent, $task_id;
예제 #5
0
if ($task_log_id) {
    if (!$canEdit) {
        $AppUI->redirect("m=public&a=access_denied");
    }
    $log->load($task_log_id);
} else {
    if (!$canAdd) {
        $AppUI->redirect("m=public&a=access_denied");
    }
    $log->task_log_task = $task_id;
    $log->task_log_name = $obj->task_name;
}
// Check that the user is at least assigned to a task
$task = new CTask();
$task->load($task_id);
if (!$task->canAccess($AppUI->user_id)) {
    $AppUI->redirect('m=public&a=access_denied');
}
// Lets check which cost codes have been used before
/*$sql = "select distinct task_log_costcode
        from task_log
        where task_log_costcode != ''
        order by task_log_costcode";
$task_log_costcodes = array(""); // Let's add a blank default option
$task_log_costcodes = array_merge($task_log_costcodes, db_loadColumn($sql));
*/
$proj =& new CProject();
$proj->load($obj->task_project);
$sql = "SELECT billingcode_id, billingcode_name\n        FROM billingcode\n        WHERE billingcode_status=0\n        AND (company_id='{$proj->project_company}' OR company_id = 0)\n        ORDER BY billingcode_name";
$task_log_costcodes[0] = '';
$ptrc = db_exec($sql);
function showtask_pr_ed(&$arr, $level = 0, $today_view = false)
{
    global $AppUI, $done;
    //Check for Tasks Access
    $tmpTask = new CTask();
    $tmpTask->load($arr['task_id']);
    $canAccess = $tmpTask->canAccess();
    if (!$canAccess) {
        return false;
    }
    $htmlHelper = new w2p_Output_HTMLHelper($AppUI);
    $htmlHelper->df .= ' ' . $AppUI->getPref('TIMEFORMAT');
    $done[] = $arr['task_id'];
    $s = '<tr>';
    // dots
    $s .= '<td style="width: ' . ($today_view ? '20%' : '50%') . '" class="data _name">';
    for ($y = 0; $y < $level; $y++) {
        if ($y + 1 == $level) {
            $image = w2PfindImage('corner-dots.gif', $m);
        } else {
            $image = w2PfindImage('shim.gif', $m);
        }
        $s .= '<img src="' . $image . '" width="16" height="12"  border="0" alt="" />';
    }
    // name link
    $alt = mb_strlen($arr['task_description']) > 80 ? mb_substr($arr['task_description'], 0, 80) . '...' : $arr['task_description'];
    // instead of the statement below
    $alt = mb_str_replace('"', "&quot;", $alt);
    $alt = mb_str_replace("\r", ' ', $alt);
    $alt = mb_str_replace("\n", ' ', $alt);
    $open_link = w2PshowImage('collapse.gif');
    if ($arr['task_milestone'] > 0) {
        $s .= '&nbsp;<b>' . $arr["task_name"] . '</b><!--</a>--> <img src="' . w2PfindImage('icons/milestone.gif', $m) . '" border="0" alt="" />';
    } elseif ($arr['task_dynamic'] == '1') {
        $s .= $open_link;
        $s .= '<strong>' . $arr['task_name'] . '</strong>';
    } else {
        $s .= $arr['task_name'];
    }
    $s .= '</td>';
    $s .= $htmlHelper->createCell('task_percent_complete', $arr['task_percent_complete']);
    $s .= $htmlHelper->createCell('task_start_date', $arr['task_start_date']);
    $s .= $htmlHelper->createCell('task_end_date', $arr['task_end_date']);
    $s .= $htmlHelper->createCell('last_update', $arr['last_update']);
    $s .= '</tr>';
    return $s;
}
예제 #7
0
$task_id = intval(dPgetParam($_GET, 'task_id', 0));
$task_log_id = intval(dPgetParam($_GET, 'task_log_id', 0));
$reminded = intval(dPgetParam($_GET, 'reminded', 0));
$obj = new CTask();
$obj->peek($task_id);
//we need to peek at the task's data to determine its access level
$msg = '';
// check permissions for this record
$canAccess = getPermission($m, 'access', $task_id);
$canRead = getPermission($m, 'view', $task_id);
$canEdit = getPermission($m, 'edit', $task_id);
// check if this record has dependencies to prevent deletion
$canDelete = $obj->canDelete($msg, $task_id);
// check permissions for this record (module level)
$canReadModule = getPermission($m, 'view');
if (!($canRead && $obj->canAccess($AppUI->user_id))) {
    $AppUI->redirect('m=public&a=access_denied');
}
$q = new DBQuery();
$q->addTable('tasks');
$q->leftJoin('users', 'u1', 'u1.user_id = task_owner');
$q->leftJoin('projects', 'p', 'p.project_id = task_project');
$q->leftJoin('task_log', 'tl', 'tl.task_log_task = task_id');
$q->addWhere('task_id = ' . $task_id);
$q->addQuery('tasks.*');
$q->addQuery('project_name, project_color_identifier');
$q->addQuery('u1.user_username as username');
$q->addQuery('ROUND(SUM(task_log_hours),2) as log_hours_worked');
$q->addGroup('task_id');
//$obj = null;
$sql = $q->prepare();
예제 #8
0
 public function getAllowedTaskList($notUsed = null, $task_project = 0, $orderby = '')
 {
     $results = array();
     $q = $this->_getQuery();
     $q->addQuery('task_id, task_name, task_parent, task_access, task_owner');
     $q->addQuery('task_start_date, task_end_date, task_percent_complete');
     $q->addQuery('task_duration, task_duration_type');
     $q->addOrder('task_parent, task_parent = task_id desc');
     $q->addTable('tasks', 't');
     if ($task_project) {
         $q->addWhere('task_project = ' . (int) $task_project);
     }
     $orderby = property_exists($this, $orderby) ? $orderby : 'task_parent, task_id desc';
     $q->addOrder($orderby);
     $task_list = $q->loadList();
     $obj = new CTask();
     foreach ($task_list as $task) {
         $obj->load($task['task_id']);
         $canAccess = $obj->canAccess();
         if ($canAccess) {
             $results[] = $task;
         }
     }
     return $results;
 }
예제 #9
0
        if ($i != count($gantt_arr) - 1 && $gantt_arr[$i + 1][1] > $gantt_arr[$i][1]) {
            // it's not a leaf => remove
            array_splice($gantt_arr, $i, 1);
            continue;
        }
    }
}
$gantt->loadTaskArray($gantt_arr);
$row = 0;
for ($i = 0, $i_cmp = count($gantt_arr); $i < $i_cmp; $i++) {
    $a = $gantt_arr[$i][0];
    $level = $gantt_arr[$i][1];
    $caption = '';
    $tmpTask = new CTask();
    $tmpTask->load($a['task_id']);
    $canAccess = $tmpTask->canAccess();
    if ($canAccess) {
        if ($hide_task_groups) {
            $level = 0;
        }
        $name = $a['task_name'];
        $name = mb_strlen($name) > 35 ? mb_substr($name, 0, 30) . '...' : $name;
        $name = str_repeat('   ', $level) . $name;
        $pname = $a['project_name'];
        $pname = mb_strlen($pname) > 25 ? mb_substr($pname, 0, 20) . '...' : $pname;
        //using new jpGraph determines using Date object instead of string
        $start = (int) $a['task_start_date'] ? new w2p_Utilities_Date($AppUI->formatTZAwareTime($a['task_start_date'], '%Y-%m-%d %T')) : new w2p_Utilities_Date();
        $start = $start->getDate();
        $end = (int) $a['task_end_date'] ? new w2p_Utilities_Date($AppUI->formatTZAwareTime($a['task_end_date'], '%Y-%m-%d %T')) : new w2p_Utilities_Date();
        $end = $end->getDate();
        $progress = (int) $a['task_percent_complete'];
예제 #10
0
//TODO: this method should be moved to CTaskLog
$logs = $project->getTaskLogs(null, $project_id, $user_id, $hide_inactive, $hide_complete, $cost_code);
$s = '';
$hrs = 0;
$canEdit = canEdit('task_log');
$htmlHelper = new w2p_Output_HTMLHelper($AppUI);
$billingCategory = w2PgetSysVal('BudgetCategory');
$durnTypes = w2PgetSysVal('TaskDurationType');
$status = w2PgetSysVal('TaskStatus');
$task_types = w2PgetSysVal('TaskType');
$customLookups = array('budget_category' => $billingCategory, 'task_duration_type' => $durnTypes, 'task_status' => $status, 'task_type' => $task_types);
$task = new CTask();
if (count($logs)) {
    foreach ($logs as $row) {
        $task->task_id = $row['task_id'];
        if (!$task->canAccess()) {
            /** If the user isn't allowed to see the task, don't show the logs. */
            continue;
        }
        $s .= '<tr bgcolor="white" valign="top"><td class="data _edit">';
        if ($canEdit) {
            $s .= '<a href="?m=tasks&a=view&task_id=' . $row['task_id'] . '&tab=1&task_log_id=' . $row['task_log_id'] . '">' . w2PshowImage('icons/stock_edit-16.png', 16, 16, '') . "\n\t\t</a>";
        }
        $s .= '</td>';
        $htmlHelper->stageRowData($row);
        foreach ($fieldList as $index => $column) {
            $s .= $htmlHelper->createCell($fieldList[$index], $row[$fieldList[$index]], $customLookups);
        }
        $s .= '<td class="data _delete">';
        if ($canDelete) {
            $s .= '<a href="javascript:delIt2(' . $row['task_log_id'] . ');" title="' . $AppUI->_('delete log') . '">' . w2PshowImage('icons/stock_delete-16.png', 16, 16, '') . '</a>';