/** * Delete a person */ function personDelete() { global $PH; ### get person #### $ids = getPassedIds('person', 'people_*'); if (!$ids) { $PH->abortWarning(__("Select some people to delete")); return; } $counter = 0; $errors = 0; foreach ($ids as $id) { if (!($person = Person::getEditableById($id))) { $PH->abortWarning("Invalid person-id!"); } ### people in project can't be deleted ### if ($pps = $person->getProjectPeople(array('alive_only' => false, 'visible_only' => false))) { new FeedbackWarning(sprintf(__('<b>%s</b> has been assigned to projects and can not be deleted. However, we deativated his right to login and removed him from all projects.'), $person->getLink())); ### delete from projects foreach ($pps as $pp) { if (!$pp->delete()) { new FeedbackWarning("Failed to delete project assignment."); } } ### disable account $person->can_login = 0; $person->update(); } else { if ($person->delete()) { $counter++; } else { $errors++; } } } if ($errors) { new FeedbackWarning(sprintf(__("Failed to delete %s people"), $errors)); } else { new FeedbackMessage(sprintf(__("Moved %s people to trash"), $counter)); } ### display personList #### $PH->show('personList'); }
/** * export selected efforts as a CSV ready for copy and paste into a spread-sheet @ingroup pages ** */ function effortShowAsCSV() { global $PH; global $g_effort_status_names; $effort_ids = getPassedIds('effort', 'efforts_*'); if (!$effort_ids) { $PH->abortWarning(__("Select some efforts(s) to show")); exit; } $efforts = array(); $different_fields = array(); $edit_fields = array('status', 'pub_level', 'task'); foreach ($effort_ids as $id) { if ($effort = Effort::getEditableById($id)) { $efforts[] = $effort; ### check project for first task if (count($efforts) == 1) { ### make sure all are of same project ### if (!($project = Project::getVisibleById($effort->project))) { $PH->abortWarning('could not get project'); } } else { if ($effort->project != $efforts[0]->project) { $PH->abortWarning(__("For editing all efforts must be of same project.")); } foreach ($edit_fields as $field_name) { if ($effort->{$field_name} != $efforts[0]->{$field_name}) { $different_fields[$field_name] = true; } } } } } $page = new Page(array('use_jscalendar' => true)); $page->cur_tab = 'projects'; $page->options[] = new naviOption(array('target_id' => 'effortEdit')); $page->type = __("Edit multiple efforts", "Page title"); $page->title = sprintf(__("%s efforts for copy and pasting into a spread-sheet", "Page title"), count($efforts)); echo new PageHeader(); echo new PageContentOpen(); $block = new PageBlock(array('id' => 'functions', 'reduced_header' => true)); $block->render_blockStart(); $format = "[Date][Weekday][Task][Comment][Duration]"; preg_match_all("/\\[(.*?)\\]/", $format, $matches); $overallDuration = 0; echo "<textarea style='width:96%; height:300px;'>"; echo join("\t", $matches[1]) . "\n"; foreach ($efforts as $e) { preg_match_all("/\\[(.*?)\\]/", $format, $matches); $separator = ""; foreach ($matches[1] as $matchedFormat) { echo $separator; switch ($matchedFormat) { case "Date": echo gmstrftime("%Y-%m-%d", strToGMTime($e->time_start)); break; case "Weekday": echo gmstrftime("%a", strToGMTime($e->time_start)); break; case "Task": if ($t = Task::getVisibleById($e->task)) { echo $t->name; } break; case "Comment": echo $e->name; break; case "Duration": $durationInMinutes = round((strToGMTime($e->time_end) - strToGMTime($e->time_start)) / 60, 0); $roundUpTo15 = ceil($durationInMinutes / 15) * 15 / 60; $overallDuration += $roundUpTo15; echo number_format($roundUpTo15, 2, $dec_point = ',', ''); break; } $separator = "\t"; } echo "\n"; } echo "</textarea>"; echo "<br>"; echo __("Overall Duration:") . $overallDuration . "h"; $block->render_blockEnd(); echo new PageContentClose(); echo new PageHtmlEnd(); exit; }
/** * move comments to folder... */ function commentsMoveToFolder() { global $PH; $comment_ids = getPassedIds('comment', 'comments_*'); if (!$comment_ids) { $PH->abortWarning(__("Select some comments to move")); return; } /** * if folder was given, directly move tasks... */ $target_id = -1; # target is unknown $folder_ids = getPassedIds('folder', 'folders_*'); if (count($folder_ids) == 1) { if ($folder_task = Task::getVisibleById($folder_ids[0])) { $target_id = $folder_task->id; } } else { if (get('from_selection')) { $target_id = 0; # to ungrout to root? } } if ($target_id != -1) { if ($target_id != 0) { if (!($target_task = Task::getEditableById($target_id))) { $PH->abortWarning(__("insufficient rights")); } } $count = 0; foreach ($comment_ids as $id) { if ($comment = Comment::getEditableById($id)) { $comment->task = $target_id; /** * @@@ do we have to reset ->comment as well? * * this splits discussions into separate comments... */ $comment->comment = 0; $comment->update(); } else { new FeedbackWarning(sprintf(__("Can not edit comment %s"), asHtml($comment->name))); } } ### return to from-page? ### if (!$PH->showFromPage()) { $PH->show('home'); } exit; } /** * build page folder list to select target... */ require_once confGet('DIR_STREBER') . 'lists/list_tasks.inc.php'; ### get project #### if (!($comment = Comment::getVisibleById($comment_ids[0]))) { $PH->abortWarning("could not get comment", ERROR_BUG); } if (!($project = Project::getVisibleById($comment->project))) { $PH->abortWarning("task without project?", ERROR_BUG); } $page = new Page(array('use_jscalendar' => false, 'autofocus_field' => 'company_name')); $page->cur_tab = 'projects'; $page->type = __("Edit tasks"); $page->title = $project->name; $page->title_minor = __("Select one folder to move comments into"); $page->crumbs = build_project_crumbs($project); $page->options[] = new NaviOption(array('target_id' => 'commentsMoveToFolder')); echo new PageHeader(); echo new PageContentOpen(); echo __("... or select nothing to move to project root"); ### write selected comments as hidden fields ### foreach ($comment_ids as $id) { if ($comment = Comment::getEditableById($id)) { echo "<input type=hidden name='comments_{$id}_chk' value='1'>"; } } $list = new ListBlock_tasks(); $list->reduced_header = true; $list->query_options['show_folders'] = true; $list->query_options['folders_only'] = true; $list->query_options['project'] = $project->id; $list->groupings = NULL; $list->block_functions = NULL; $list->id = 'folders'; unset($list->columns['project']); unset($list->columns['status']); unset($list->columns['date_start']); unset($list->columns['days_left']); unset($list->columns['created_by']); unset($list->columns['label']); $list->no_items_html = __("No folders in this project..."); $list->functions = array(); $list->active_block_function = 'tree'; $list->print_automatic($project); echo "<input type=hidden name='from_selection' value='1'>"; # keep flag to ungroup comments echo "<input type=hidden name='project' value='{$project->id}'>"; $button_name = __("Move items"); echo "<input class=button2 type=submit value='{$button_name}'>"; $PH->go_submit = 'commentsMoveToFolder'; echo new PageContentClose(); echo new PageHtmlEnd(); }
/** * Unlink a person from a company @ingroup pages */ function personCompaniesDelete() { global $PH; $id = getOnePassedId('person', 'people_*'); $person = Person::getEditableById($id); if (!$person) { $PH->abortWarning("Could not get object..."); } $company_ids = getPassedIds('company', 'companies_*'); if (!$company_ids) { $PH->abortWarning(__("No companies selected...")); } $employments = $person->getEmployments(); $counter = 0; $errors = 0; foreach ($company_ids as $cid) { if (!($company = Company::getEditableById($cid))) { $PH->abortWarning("Could not access company by id"); } $assigned_to = false; foreach ($employments as $e) { if ($e->company == $company->id) { $assigned_to = true; $e_id = $e->id; if ($assigned_to) { $e_remove = Employment::getEditableById($e_id); if (!$e_remove) { $PH->abortWarning("Could not access employment by id"); } else { if ($e_remove->delete()) { $counter++; } else { $errors++; } } } else { $PH->abortWarning("Company isn't related to this person"); } } } } if ($errors) { new FeedbackWarning(sprintf(__("Failed to remove %s companies"), $errors)); } else { new FeedbackMessage(sprintf(__("Removed %s companies"), $counter)); } if (!$PH->showFromPage()) { $PH->show('personView', array('person' => $person->id)); } }
/** * Restoring (i.e. undelete) items @ingroup pages */ function itemsRestore() { global $PH; ### get effort #### $ids = getPassedIds('item', 'items_*'); if (!$ids) { $PH->abortWarning(__("Select some items to restore")); return; } $counter = 0; $errors = 0; foreach ($ids as $id) { $i = DbProjectItem::getEditableById($id); if (!$i) { $PH->abortWarning("Invalid item-id!"); } if ($i->state != -1) { new FeedbackMessage(sprintf(__('Item %s does not need to be restored'), $i->id)); $errors++; continue; } $i->state = 1; if ($i->update()) { $counter++; } else { $errors++; } } if ($errors) { new FeedbackWarning(sprintf(__("Failed to restore %s items"), $errors)); } else { new FeedbackMessage(sprintf(__("Restored %s items"), $counter)); } if (!$PH->showFromPage()) { $PH->show('home'); } }
/** * Submit changes to multiple tasks * * @ingroup pages */ function taskEditMultipleSubmit() { global $PH; $ids = getPassedIds('tsk', 'tasks_*'); if (!$ids) { $PH->abortWarning(__("Select some task(s) to mark as approved"), ERROR_NOTE); return; } $count = 0; $errors = 0; $number = get('number'); ### cancel? ### if (get('form_do_cancel')) { if (!$PH->showFromPage()) { $PH->show('home'); } exit; } foreach ($ids as $id) { if ($task = Task::getEditableById($id)) { $count++; $change = false; $status_old = $task->status; ### status ### if ($count == 1) { if (!($project = Project::getVisibleById($task->project))) { $PH->abortWarning('could not get project'); } $team = array(); foreach ($project->getPeople() as $p) { $team[$p->id] = $p; } } $task_assigned_people = array(); $task_assignments = array(); $task_people_overwrite = array(); $task_people_new = array(); $task_people_delete = array(); ## previous assigend people ## if ($task_people = $task->getAssignedPeople(false)) { foreach ($task_people as $tp) { $task_assigned_people[$tp->id] = $tp; } } ## previous assignements ## if ($task_assign = $task->getAssignments()) { foreach ($task_assign as $ta) { $task_assignments[$ta->person] = $ta; } } ## different assigned people ## ## overwrite ?? ## $ass1 = get('task_assignement_diff'); if ($ass1 && $ass1 != '__dont_change__') { $task_people_overwrite[] = $ass1; foreach ($task_assignments as $key => $value) { $task_people_delete[] = $value; } $change = true; } ## new ?? ## $ass2 = get('task_assignement_also_diff'); if ($ass2 && $ass2 != '__select_person__') { $task_people_new[] = $ass2; $change = true; } $different = get('different_ass'); if (isset($different) && !$different) { if (isset($task_assignments) && count($task_assignments) != 0) { foreach ($task_assignments as $tid => $t_old) { $id_new = get('task_assign_to_' . $tid); ## no changes ## if ($tid == $id_new) { continue; } if ($id_new == '__none__') { if (!$t_old) { continue; } $task_people_delete[] = $t_old; continue; } $task_people_delete[] = $t_old; $task_people_overwrite[] = $id_new; } } else { $id_new = get('task_assign_to___none__'); if ($id_new && $id_new != '__none__') { $task_people_new[] = $id_new; } } $id_new = get('task_assign_to_0'); if ($id_new != '__select_person__') { if (!isset($task_assignments[$id_new])) { $task_people_new[] = $id_new; } } $change = true; } ### category ### $v = get('task_category'); if (!is_null($v) && $v != '__dont_change__' && $v != $task->category) { $task->category = $v; $change = true; } ### status ### $status = get('task_status'); if ($status && $status != '__dont_change__' && $status != $task->status) { $task->status = $status; $change = true; } ### prio ### $prio = get('task_prio'); if ($prio && $prio != '__dont_change__' && $prio != $task->prio) { $task->prio = $prio; $change = true; } ### pub level ### $pub_level = get('task_pub_level'); if ($pub_level && $pub_level != '__dont_change__' && $pub_level != $task->pub_level) { if ($pub_level > $task->getValidUserSetPublicLevel()) { $PH->abortWarning('invalid data', ERROR_RIGHTS); } $task->pub_level = $pub_level; $change = true; } ### label ### $label = get('task_label'); if ($label && $label != '__dont_change__' && $label != $task->label) { $task->label = $label; $change = true; } ### for milestone ### $fm = get('task_for_milestone'); if (!is_null($fm) && $fm != '__dont_change__' && $task->for_milestone != $fm) { if ($fm) { if (($m = Task::getVisibleById($fm)) && $m->isMilestoneOrVersion()) { $task->for_milestone = $fm; $change = true; } else { continue; } } else { $task->for_milestone = 0; $change = true; } } ### resolve version ### $rv = get('task_resolved_version'); if (!is_null($rv) && $rv != '__dont_change__' && $task->resolved_version != $rv) { if ($rv && $rv != -1) { if ($v = Task::getVisibleById($rv)) { if ($v->isMilestoneOrVersion()) { $task->resolved_version = $rv; $change = true; } } else { continue; } } else { if ($rv == -1) { $task->resolved_version = $rv; $change = true; } else { $task->resolved_version = 0; $change = true; } } } ### resolve reason ### $rs = get('task_resolve_reason'); if ($rs && $rs != '__dont_change__' && $rs != $rs->resolve_reason) { $task->resolve_reason = $rs; $change = true; } if ($change) { ### Check if now longer new ### if ($status_old == $task->status && $task->status == STATUS_NEW) { global $auth; if ($task->created < $auth->cur_user->last_login) { $task->status = STATUS_OPEN; } } ## overwrite assigend people ## if (isset($task_people_overwrite)) { if (isset($task_people_delete)) { foreach ($task_people_delete as $tpd) { $tpd->delete(); } } foreach ($task_people_overwrite as $tpo) { $task_pers_over = new TaskPerson(array('person' => $team[$tpo]->id, 'task' => $task->id, 'comment' => '', 'project' => $project->id)); $task_pers_over->insert(); } } ## add new person ## if (isset($task_people_new)) { foreach ($task_people_new as $tpn) { if (!isset($task_assigned_people[$tpn])) { $task_pers_new = new TaskPerson(array('person' => $team[$tpn]->id, 'task' => $task->id, 'comment' => '', 'project' => $project->id)); $task_pers_new->insert(); } } } ##update## $task->update(); $task->nowChangedByUser(); } } else { $errors++; } } ### compose message ### if ($errors) { new FeedbackWarning(sprintf(__('%s tasks could not be written'), $errors)); } else { if ($count) { new FeedbackMessage(sprintf(__('Updated %s tasks tasks'), $count)); } } ### return to from-page? ### if (!$PH->showFromPage()) { $PH->show('taskView', array('tsk' => $task->id)); } }
/** * Edit a task * * @ingroup pages */ function taskEdit($task = NULL) { global $PH; ### object or from database? ### if (!$task) { $ids = getPassedIds('tsk', 'tasks_*'); if (!$ids) { $PH->abortWarning(__("Select some task(s) to edit"), ERROR_NOTE); return; } else { if (count($ids) > 1) { $PH->show('taskEditMultiple'); exit; } else { if (!($task = Task::getEditableById($ids[0]))) { $PH->abortWarning(__("You do not have enough rights to edit this task"), ERROR_RIGHTS); } } } } ### get parent project #### if (!($project = Project::getVisibleById($task->project))) { $PH->abortWarning("FATAL error! parent project not found"); } ### abort, if not enough rights ### $project->validateEditItem($task); $page = new Page(array('use_jscalendar' => true, 'autofocus_field' => 'task_name')); initPageForTask($page, $task, $project); if ($task->id) { $page->title = $task->name; $page->title_minor = $task->short; } else { if ($task->category == TCATEGORY_MILESTONE) { $page->title = __("New milestone"); } else { if ($task->category == TCATEGORY_VERSION) { $page->title = __("New version"); } else { if ($task->category == TCATEGORY_DOCU) { $page->title = __("New topic"); } else { if ($task->category == TCATEGORY_FOLDER) { $page->title = __("New folder"); } else { $page->title = __("New task"); if ($task->parent_task && ($parent_task = Task::getVisibleById($task->parent_task))) { $page->title_minor = sprintf(__('for %s', 'e.g. new task for something'), $parent_task->name); } else { $page->title_minor = sprintf(__('for %s', 'e.g. new task for something'), $project->name); } } } } } } echo new PageHeader(); echo new PageContentOpen(); require_once confGet('DIR_STREBER') . 'render/render_form.inc.php'; global $auth; global $REPRODUCIBILITY_VALUES; global $g_prio_names; global $g_status_names; $block = new PageBlock(array('id' => 'functions')); $block->render_blockStart(); $form = new PageForm(); $form->button_cancel = true; $form->add($task->fields['name']->getFormElement($task)); $list = array(); if ($task->category == TCATEGORY_MILESTONE || $task->category == TCATEGORY_VERSION) { $list = array(TCATEGORY_MILESTONE, TCATEGORY_VERSION); ### make sure it's valid if ($task->category != TCATEGORY_MILESTONE || $task->category != TCATEGORY_VERSION) { if ($task->is_released > RELEASED_UPCOMMING) { $task->category = TCATEGORY_VERSION; } else { $task->category = TCATEGORY_MILESTONE; } } } else { $list = array(); if ($project->settings & PROJECT_SETTING_ENABLE_TASKS) { $list[] = TCATEGORY_TASK; } if ($project->settings & PROJECT_SETTING_ENABLE_BUGS) { $list[] = TCATEGORY_BUG; } $list[] = TCATEGORY_DOCU; $list[] = TCATEGORY_FOLDER; } global $g_tcategory_names; $cats = array(); foreach ($list as $c) { $cats[$c] = $g_tcategory_names[$c]; } $form->add(new Form_Dropdown('task_category', __("Display as"), array_flip($cats), $task->category)); ### warning if folder with subtasks ### if ($task->id && $task->category == TCATEGORY_FOLDER && ($num_subtasks = count($task->getSubtasks()))) { $form->add(new Form_CustomHtml('<p><label></label>' . sprintf(__("This folder has %s subtasks. Changing category will ungroup them."), $num_subtasks) . '</p>')); } $form->add($tab_group = new Page_TabGroup()); $tab_group->add($tab = new Page_Tab('task', __("Task"))); ### normaltasks and folders ## if (!$task->isMilestoneOrVersion()) { if ($project->settings & PROJECT_SETTING_ENABLE_MILESTONES) { $tab->add(new Form_DropdownGrouped('task_for_milestone', __('For Milestone'), $project->buildPlannedForMilestoneList(), $task->for_milestone)); } ### prio ### if ($task->category != TCATEGORY_MILESTONE && $task->category != TCATEGORY_VERSION) { $tab->add(new Form_Dropdown('task_prio', __("Prio", "Form label"), array_flip($g_prio_names), $task->prio)); } } ### for existing tasks, get already assigned if ($task->id) { $assigned_people = $task->getAssignedPeople(); #$task_assignments = $task->getAssignments(); } else { ### check new assigments ### $count = 0; while ($id_new = get('task_assign_to_' . $count)) { $count++; ### check if already assigned ### if ($p = Person::getVisibleById($id_new)) { $assigned_people[] = $p; } } if (!$count) { $parents = $task->getFolder(); if ($parents) { $parents = array_reverse($parents); foreach ($parents as $p) { if ($ap = $p->getAssignedPeople()) { $assigned_people = $ap; break; } } } } } $team = array(__('- select person -') => 0); ### create team-list ### foreach ($project->getPeople() as $p) { $team[$p->name] = $p->id; } ### create drop-down-lists ### $count_new = 0; $count_all = 0; if (isset($assigned_people)) { foreach ($assigned_people as $ap) { if (!($p = Person::getVisibleById($ap->id))) { continue; # skip if invalid person } if ($task->id) { $tab->add(new Form_Dropdown('task_assigned_to_' . $ap->id, __("Assigned to"), $team, $ap->id)); } else { $tab->add(new Form_Dropdown('task_assign_to_' . $count_new, __("Assign to"), $team, $ap->id)); $count_new++; } $count_all++; unset($team[$ap->name]); } } ### add empty drop-downlist for new assignments ### $str_label = $count_all == 0 ? __("Assign to", "Form label") : __("Also assign to", "Form label"); $tab->add(new Form_Dropdown("task_assign_to_{$count_new}", $str_label, $team, 0)); ### completion ### if (!$task->is_released > RELEASED_UPCOMMING) { #$form->add($task->fields['estimated' ]->getFormElement($task)); $ar = array(__('undefined') => -1, '0%' => 0, '10%' => 10, '20%' => 20, '30%' => 30, '40%' => 40, '50%' => 50, '60%' => 60, '70%' => 70, '80%' => 80, '90%' => 90, '95%' => 95, '98%' => 98, '99%' => 99, '100%' => 100); $tab->add(new Form_Dropdown('task_completion', __("Completed"), $ar, $task->completion)); } $st = array(); foreach ($g_status_names as $s => $n) { if ($s >= STATUS_NEW) { $st[$s] = $n; } } if ($task->isMilestoneOrVersion()) { unset($st[STATUS_NEW]); } $field_status = new Form_Dropdown('task_status', "Status", array_flip($st), $task->status); if ($task->fields['status']->invalid) { $field_status->invalid = true; } $tab->add($field_status); if (!$task->isMilestoneOrVersion()) { if ($project->settings & PROJECT_SETTING_ENABLE_MILESTONES) { ### resolved version ### $tab->add(new Form_DropdownGrouped('task_resolved_version', __('Resolved in'), $project->buildResolvedInList(), $task->resolved_version)); } ### resolved reason ### global $g_resolve_reason_names; $tab->add(new Form_Dropdown('task_resolve_reason', __('Resolve reason'), array_flip($g_resolve_reason_names), $task->resolve_reason)); } $tab_group->add($tab = new Page_Tab("bug", __("Bug Report"))); ### use issue-report ### global $g_severity_names; global $g_reproducibility_names; ### create new one ### if ($task->issue_report <= 0) { $issue = new Issue(array('id' => 0)); ### get recent issue-reports ### if ($recent_ir = Issue::getCreatedRecently()) { $default_version = ''; $default_plattform = ''; $default_production_build = ''; $default_os = ''; foreach ($recent_ir as $ir) { if ($ir->project == $project->id) { if (!$issue->version && $ir->version) { $issue->version = $ir->version; } if (!$issue->plattform && $ir->plattform) { $issue->plattform = $ir->plattform; } if (!$issue->os && $ir->os) { $issue->os = $ir->os; } if (!$issue->production_build && $ir->production_build) { $issue->production_build = $ir->production_build; } } } } } else { /** * note: if task is visible ignore visibility of issue report */ $issue = Issue::getById($task->issue_report); } if ($issue) { $tab->add(new Form_Dropdown('issue_severity', __("Severity", "Form label, attribute of issue-reports"), array_flip($g_severity_names), $issue->severity)); $tab->add(new Form_Dropdown('issue_reproducibility', __("Reproducibility", "Form label, attribute of issue-reports"), array_flip($g_reproducibility_names), $issue->reproducibility)); foreach ($issue->fields as $field) { $tab->add($field->getFormElement($issue)); } $tab->add(new Form_HiddenField('task_issue_report', '', $task->issue_report)); } else { trigger_error("could not get Issue with id ({$task->issue}-report)", E_USER_NOTICE); } $tab_group->add($tab = new Page_Tab("timing", __("Timing"))); ### estimated ### if (!$task->isMilestoneOrVersion()) { #$tab->add($task->fields['estimated' ]->getFormElement($task)); $ar = array(__('undefined') => 0, __('30 min') => 30 * 60, __('1 h') => 60 * 60, __('2 h') => 2 * 60 * 60, __('4 h') => 4 * 60 * 60, __('1 Day') => 1 * confGet('WORKHOURS_PER_DAY') * 60 * 60, __('2 Days') => 2 * confGet('WORKHOURS_PER_DAY') * 60 * 60, __('3 Days') => 3 * confGet('WORKHOURS_PER_DAY') * 60 * 60, __('4 Days') => 4 * confGet('WORKHOURS_PER_DAY') * 60 * 60, __('1 Week') => 1 * confGet('WORKDAYS_PER_WEEK') * confGet('WORKHOURS_PER_DAY') * 60 * 60, __('2 Weeks') => 2 * confGet('WORKDAYS_PER_WEEK') * confGet('WORKHOURS_PER_DAY') * 60 * 60, __('3 Weeks') => 3 * confGet('WORKDAYS_PER_WEEK') * confGet('WORKHOURS_PER_DAY') * 60 * 60); $tab->add(new Form_Dropdown('task_estimated', __("Estimated time"), $ar, $task->estimated)); $tab->add(new Form_Dropdown('task_estimated_max', __("Estimated worst case"), $ar, $task->estimated_max)); } ### planned time ### if (!$task->isMilestoneOrVersion()) { $tab->add($task->fields['planned_start']->getFormElement($task)); } $tab->add($task->fields['planned_end']->getFormElement($task)); if ($task->isMilestoneOrVersion()) { global $g_released_names; $tab->add(new Form_Dropdown('task_is_released', __("Release as version", "Form label, attribute of issue-reports"), array_flip($g_released_names), $task->is_released)); $tab->add($task->fields['time_released']->getFormElement($task)); } $tab_group->add($tab = new Page_Tab('description', __("Description"))); $e = $task->fields['description']->getFormElement($task); $e->rows = 20; $tab->add($e); $tab_group->add($tab = new Page_Tab('display', __("Display"))); ### short ### $tab->add($task->fields['short']->getFormElement($task)); ### order id ### $tab->add($task->fields['order_id']->getFormElement($task)); ### Shows as news ### $tab->add($task->fields['is_news']->getFormElement($task)); ### Shows Folder as documentation ### $tab->add($task->fields['show_folder_as_documentation']->getFormElement($task)); ### public-level ### if (($pub_levels = $task->getValidUserSetPublicLevels()) && count($pub_levels) > 1) { $tab->add(new Form_Dropdown('task_pub_level', __("Publish to"), $pub_levels, $task->pub_level)); } ### label ### if (!$task->isOfCategory(TCATEGORY_VERSION, TCATEGORY_MILESTONE, TCATEGORY_FOLDER)) { $labels = array(__('undefined') => 0); $counter = 1; foreach (explode(",", $project->labels) as $l) { $labels[$l] = $counter++; } $tab->add(new Form_Dropdown('task_label', __("Label"), $labels, $task->label)); } if (confGet('INTERNAL_COST_FEATURE') && $auth->cur_user->user_rights & RIGHT_VIEWALL && $auth->cur_user->user_rights & RIGHT_EDITALL) { $tab_group->add($tab = new Page_Tab("internal", __("Internal"))); $tab->add($task->fields['calculation']->getFormElement($task)); } /** * to reduce spam, enforce captcha test for guests */ global $auth; if ($auth->cur_user->id == confGet('ANONYMOUS_USER')) { $form->addCaptcha(); } $form->add($task->fields['parent_task']->getFormElement($task)); #echo "<input type=hidden name='tsk' value='$task->id'>"; $form->add(new Form_HiddenField('tsk', '', $task->id)); #echo "<input type=hidden name='task_project' value='$project->id'>"; $form->add(new Form_HiddenField('task_project', '', $project->id)); ### create another task ### if ($task->id == 0) { $checked = get('create_another') ? 'checked' : ''; $form->form_options[] = "<input id='create_another' name='create_another' type=checkbox {$checked}><label for='create_another'>" . __("Create another task after submit") . "</label>"; } echo $form; $PH->go_submit = 'taskEditSubmit'; if ($return = get('return')) { echo "<input type=hidden name='return' value='{$return}'>"; } $block->render_blockEnd(); #@@@ passing project-id is an security-issue, because it might allow to add tasks to unverified projects. # Double-checking project-rights in taskEditSubmit() required echo new PageContentClose(); echo new PageHtmlEnd(); }
/** * get exactly one html-passed id * - set PH->message if multiple selected */ function getOnePassedId($name = false, $wild = false, $abort_on_failure = true, $message = NULL) { global $PH; if (!$message) { $message = __("No element selected? (could not find id)", "Message if a function started without items selected"); } $ids = getPassedIds($name, $wild); if (!$ids) { if ($abort_on_failure) { $PH->abortWarning($message, ERROR_NOTE); exit("aborting"); } return; } else { if (count($ids) > 1) { $message = __('only one item expected.'); if ($abort_on_failure) { $PH->abortWarning($message, ERROR_NOTE); } else { $PH->messages[] = $message; return; } } } return $ids[0]; }
/** * Deleting version(s) @ingroup pages */ function versionsDelete() { global $PH; ### get versions #### $ids = getPassedIds('version', 'versions_*'); if (!$ids) { $PH->abortWarning(__("Select some versions to delete")); return; } $counter = 0; $errors = 0; foreach ($ids as $id) { $e = Version::getEditableById($id); if (!$e) { $PH->abortWarning("Invalid version-id!"); } if ($e->delete()) { $counter++; } else { $errors++; } } if ($errors) { new FeedbackWarning(sprintf(__("Failed to delete %s versions"), $errors)); } else { new FeedbackMessage(sprintf(__("Moved %s versions to trash"), $counter)); } if (!$PH->showFromPage()) { $PH->show('home'); } }
/** * edit several bookmarks @ingroup pages */ function itemBookmarkEditMultiple($thebookmarks = NULL) { global $PH; global $auth; global $g_notitychange_period; $is_already_bookmark = array(); $bookmarks = array(); $items = array(); $edit_fields = array('notify_if_unchanged', 'notify_on_change'); $different_fields = array(); # hash containing fieldnames which are different in bookmarks if (!$thebookmarks) { $item_ids = getPassedIds('bookmark', 'bookmarks_*'); foreach ($item_ids as $is) { if ($bookmark = ItemPerson::getAll(array('item' => $is, 'person' => $auth->cur_user->id))) { if ($item = DbProjectItem::getById($bookmark[0]->item)) { $bookmarks[] = $bookmark[0]; $items[] = $item; $is_already_bookmark[$bookmark[0]->id] = true; } } } } else { $item_ids = $thebookmarks; foreach ($item_ids as $is) { if ($bookmark = ItemPerson::getAll(array('item' => $is, 'person' => $auth->cur_user->id, 'is_bookmark' => 0))) { if ($item = DbProjectItem::getById($bookmark[0]->item)) { $bookmarks[] = $bookmark[0]; $items[] = $item; $is_already_bookmark[$bookmark[0]->id] = false; } } elseif ($bookmark = ItemPerson::getAll(array('item' => $is, 'person' => $auth->cur_user->id, 'is_bookmark' => 1))) { if ($item = DbProjectItem::getById($bookmark[0]->item)) { $bookmarks[] = $bookmark[0]; $items[] = $item; $is_already_bookmark[$bookmark[0]->id] = true; } } else { $date = getGMTString(); $bookmark = new ItemPerson(array('id' => 0, 'item' => $is, 'person' => $auth->cur_user->id, 'is_bookmark' => 1, 'notify_if_unchanged' => 0, 'notify_on_change' => 0, 'created' => $date)); if ($item = DbProjectItem::getById($is)) { $bookmarks[] = $bookmark; $items[] = $item; $is_already_bookmark[$bookmark->id] = false; } } } } if (!$items) { $PH->abortWarning(__("Please select some items")); } $page = new Page(); $page->cur_tab = 'home'; $page->options = array(new NaviOption(array('target_id' => 'itemBookmarkEdit', 'name' => __('Edit bookmarks')))); $page->type = __('Edit multiple bookmarks', 'page title'); $page->title = sprintf(__('Edit %s bookmark(s)'), count($items)); $page->title_minor = __('Edit'); echo new PageHeader(); echo new PageContentOpen(); echo "<ol>"; foreach ($items as $item) { ## get item name ## $str_link = ''; if ($type = $item->type) { switch ($type) { case ITEM_TASK: require_once "db/class_task.inc.php"; if ($task = Task::getVisibleById($item->id)) { $str_link = $task->getLink(false); } break; case ITEM_COMMENT: require_once "db/class_comment.inc.php"; if ($comment = Comment::getVisibleById($item->id)) { $str_link = $comment->getLink(false); } break; case ITEM_PERSON: require_once "db/class_person.inc.php"; if ($person = Person::getVisibleById($item->id)) { $str_link = $person->getLink(false); } break; case ITEM_EFFORT: require_once "db/class_effort.inc.php"; if ($e = Effort::getVisibleById($item->id)) { $str_link = $e->getLink(false); } break; case ITEM_FILE: require_once "db/class_file.inc.php"; if ($f = File::getVisibleById($item->id)) { $str_link = $f->getLink(false); } break; case ITEM_PROJECT: require_once "db/class_project.inc.php"; if ($prj = Project::getVisibleById($item->id)) { $str_link = $prj->getLink(false); } break; case ITEM_COMPANY: require_once "db/class_company.inc.php"; if ($c = Company::getVisibleById($item->id)) { $str_link = $c->getLink(false); } break; case ITEM_VERSION: require_once "db/class_task.inc.php"; if ($tsk = Task::getVisibleById($item->id)) { $str_link = $tsk->getLink(false); } break; default: break; } } echo "<li>" . $str_link . "</li>"; } echo "</ol>"; foreach ($bookmarks as $bookmark) { foreach ($edit_fields as $field_name) { if ($bookmark->{$field_name} != $bookmarks[0]->{$field_name}) { $different_fields[$field_name] = true; } } } $block = new PageBlock(array('id' => 'functions')); $block->render_blockStart(); $form = new PageForm(); $form->button_cancel = true; $b = array(); $b[0] = __('no'); $b[1] = __('yes'); if (isset($different_fields['notify_on_change'])) { $b[-1] = '-- ' . __('keep different') . ' --'; $form->add(new Form_Dropdown('notify_on_change', __("Notify on change"), array_flip($b), -1)); } else { $form->add(new Form_Dropdown('notify_on_change', __("Notify on change"), array_flip($b), $bookmarks[0]->notify_on_change)); } $a = array(); foreach ($g_notitychange_period as $key => $value) { $a[$key] = $value; } if (isset($different_fields['notify_if_unchanged'])) { $a[-1] = '-- ' . __('keep different') . ' --'; $form->add(new Form_Dropdown('notify_if_unchanged', __("Notify if unchanged in"), array_flip($a), -1)); } else { $form->add(new Form_Dropdown('notify_if_unchanged', __("Notify if unchanged in"), array_flip($a), $bookmarks[0]->notify_if_unchanged)); } $number = 0; foreach ($bookmarks as $bm) { $form->add(new Form_HiddenField("bookmark_id_{$number}", '', $bm->id)); $form->add(new Form_HiddenField("bookmark_item_{$number}", '', $bm->item)); $form->add(new Form_HiddenField("is_already_bookmark_{$number}", '', $is_already_bookmark[$bm->id])); $number++; } $form->add(new Form_HiddenField("number", '', $number)); echo $form; $block->render_blockEnd(); $PH->go_submit = 'itemBookmarkEditMultipleSubmit'; echo new PageContentClose(); echo new PageHtmlEnd(); }
/** * remove items from user's notification list @ingroup pages */ function itemsRemoveNotification() { global $PH; global $auth; $valid = false; if ($ids = getPassedIds('task', 'tasks_*')) { $valid = true; } elseif ($ids = getPassedIds('person', 'people_*')) { $valid = true; } elseif ($ids = getPassedIds('company', 'companies_*')) { $valid = true; } elseif ($ids = getPassedIds('proj', 'projects_*')) { $valid = true; } elseif ($ids = getPassedIds('effort', 'efforts_*')) { $valid = true; } elseif ($ids = getPassedIds('comment', 'comments_*')) { $valid = true; } elseif ($ids = getPassedIds('file', 'files_*')) { $valid = true; } elseif ($ids = getPassedIds('version', 'versions_*')) { $valid = true; } else { $PH->abortWarning(__("No item(s) selected."), ERROR_NOTE); } if ($valid) { foreach ($ids as $id) { if ($item = ItemPerson::getAll(array('item' => $id, 'notify_on_change' => true))) { $item[0]->notify_on_change = false; $item[0]->update(); } } } if (!$PH->showFromPage()) { $PH->show('home'); } }
/** * Submit new teammember to a project @ingroup pages */ function projAddPersonSubmit() { global $PH; require_once confGet('DIR_STREBER') . "db/class_person.inc.php"; $id = getOnePassedId('project', ''); if (!($project = Project::getEditableById($id))) { $PH->abortWarning("Could not get object...", ERROR_FATAL); } ### get people ### $person_ids = getPassedIds('person', 'people*'); if (!$person_ids) { $PH->abortWarning(__("No people selected..."), ERROR_NOTE); } ### get team (including inactive members) ### $ppeople = $project->getProjectPeople(array('alive_only' => false, 'visible_only' => false, 'person_id' => NULL)); ### go through selected people ### foreach ($person_ids as $pid) { if (!($person = Person::getVisibleById($pid))) { $PH->abortWarning(__("Could not access person by id")); return; } #### person already employed? ### $already_in = false; $pp = NULL; foreach ($ppeople as $pp) { if ($pp->person == $person->id) { $already_in = true; break; } } ### effort-style $adjust_effort_style = $person->settings & USER_SETTING_EFFORTS_AS_DURATION ? EFFORT_STYLE_DURATION : EFFORT_STYLE_TIMES; ### add ### if (!$already_in) { $pp_new = new ProjectPerson(array('id' => 0, 'person' => $person->id, 'project' => $project->id, 'adjust_effort_style' => $adjust_effort_style, 'salary_per_hour' => $person->salary_per_hour)); ### add project-right ### global $g_user_profile_names; if ($g_user_profile_names[$person->profile]) { $profile_id = $person->profile; $pp_new->initWithUserProfile($profile_id); } else { trigger_error("person '{$person->name}' has undefined profile", E_USER_WARNING); } $pp_new->insert(); } else { if ($pp->state != 1) { $pp->state = 1; $pp->update(); new FeedbackMessage(sprintf(__("Reanimated person %s as team-member"), asHtml($person->name))); } else { new FeedbackMessage(sprintf(__("Person %s already in project"), asHtml($person->name))); } } } ### display taskView #### if (!$PH->showFromPage()) { $PH->show('projView', array('prj' => $project->id)); } }
/** * to tasks to folder... * * @ingroup pages * * NOTE: this works either... * - directly by passing a target folder in 'folder' or 'folders_*' * - in two steps, whereas * - the passed task-ids are keept as hidden fields, * - a list with folders in been rendered * - a flag 'from_selection' is set * - after submit, the kept tasks are moved to 'folders_*' * * Also check the java-script part for the ajax-functionality in js/task-move.js * * * */ function TasksMoveToFolder() { global $PH; $task_ids = getPassedIds('tsk', 'tasks_*'); if (!$task_ids) { $PH->abortWarning(__("Select some tasks to move")); exit; } /** * by default render list of folders... */ $target_task_id = -1; /** * ...but, if folder was given, directly move tasks... */ $folder_ids = getPassedIds('folder', 'folders_*'); if (count($folder_ids) == 1) { if ($folder_task = Task::getVisibleById($folder_ids[0])) { $target_task_id = $folder_task->id; } } else { if (get('from_selection')) { $target_task_id = 0; # if no folders was selected, move tasks to project root } } if ($target_task_id != -1) { $target_project_id = getOnePassedId("target_prj"); foreach ($task_ids as $task_id) { _moveTask($task_id, $target_project_id, $target_task_id); } ### return to from-page? ### if (!$PH->showFromPage()) { $PH->show('home'); } exit; } /** * build page and folder lists... */ if (!($task = Task::getVisibleById($task_ids[0]))) { $PH->abortWarning("could not get task", ERROR_BUG); } $project_id = getOnePassedId($name = 'prj', $wild = false, $abort_on_failure = false); if (!$project_id) { $project_id = $task->project; } if (!($project = Project::getVisibleById($project_id))) { $PH->abortWarning("task without project?", ERROR_BUG); } $page = new Page(array('use_jscalendar' => false)); $page->cur_tab = 'projects'; $page->type = __("Edit tasks"); $page->title = $project->name; $page->title_minor = __("Select folder to move tasks into"); $page->extra_header_html .= '<script type="text/javascript" src="js/task-move.js' . "?v=" . confGet('STREBER_VERSION') . '"></script>'; $page->extra_onload_js .= 'getAjaxListProjectFolders(' . $project_id . ');initMoveTasksUI();'; $page->crumbs = build_project_crumbs($project); $page->options[] = new NaviOption(array('target_id' => 'tasksMoveToFolder')); echo new PageHeader(); echo new PageContentOpen(); ### write project-selector ### $prj_names = array(); if ($projects = Project::getAll()) { foreach ($projects as $p) { $prj_names[$p->id] = $p->name; } ## assigne new person to ptoject ## $dropdown = new Form_Dropdown('target_prj', __('Target project', 'form label'), array_flip($prj_names), $project_id); echo $dropdown->render(); } ### write tasks as hidden entry ### foreach ($task_ids as $id) { if ($task = Task::getEditableById($id)) { echo "<input type=hidden name='tasks_{$id}_chk' value='1'>"; } } ### target container for lazy fetch with ajax ### echo "<div id='folder_list'></div>"; echo "<input type=hidden name='from_selection' value='1'>"; # keep flag to ungroup tasks $button_name = __("Move items"); echo "<input class=button2 type=submit value='{$button_name}'>"; $PH->go_submit = 'tasksMoveToFolder'; echo new PageContentClose(); echo new PageHtmlEnd(); }
/** * Delete a company * * @ingroup pages */ function companyDelete() { global $PH; ### get company #### $ids = getPassedIds('company', 'companies_*'); if (!$ids) { $PH->abortWarning(__("Select some companies to delete")); return; } $counter = 0; $errors = 0; foreach ($ids as $id) { $c = Company::getEditableById($id); if (!$c) { $PH->abortWarning("Invalid company-id!"); continue; } if ($c->delete()) { $counter++; } else { $errors++; } } if ($errors) { new FeedbackWarning(sprintf(__("Failed to delete %s companies"), $errors)); } else { new FeedbackMessage(sprintf(__("Moved %s companies to trash"), $counter)); } ### display companyList #### $PH->show('companyList'); }
/** * Remove a teammember from a project @ingroup pages */ function projectPersonDelete() { global $PH; ### get project person #### $ids = getPassedIds('projectperson', 'projectpeople_*'); if (!$ids) { $PH->abortWarning("No team-member(s) selected?", ERROR_NOTE); return; } $counter = 0; $errors = 0; foreach ($ids as $id) { $pp = ProjectPerson::getEditableById($id); if (!$pp) { $PH->abortWarning("Invalid project person-id!"); } if ($pp->delete()) { $counter++; } else { $errors++; } } if ($errors) { new FeedbackWarning(sprintf(__("Failed to remove %s members from team"), $errors)); } elseif ($counter) { new FeedbackMessage(sprintf(__("Unassigned %s team member(s) from project"), $counter)); } else { trigger_error('this should never happen'); } if (!$PH->showFromPage()) { $PH->show('projView', array('prj' => $pp->project)); } }
/** * move files to folder... * * NOTE: this works either... * - directly by passing a target folder in 'folder' or 'folders_*' * - in two steps, whereas * - the passed task-ids are keept as hidden fields, * - a list with folders is been rendered * - a flag 'from_selection' is set * - after submit, the kept tasks are moved to 'folders_*' * */ function FilesMoveToFolder() { global $PH; $file_ids = getPassedIds('file', 'files_*'); if (!$file_ids) { $PH->abortWarning(__("Select some files to move")); exit; } /** * by default render list of folders... */ $target_id = -1; /** * ...but, if folder was given, directly move files... */ $folder_ids = getPassedIds('folder', 'folders_*'); if (count($folder_ids) == 1) { if ($folder_task = Task::getVisibleById($folder_ids[0])) { $target_id = $folder_task->id; } } else { if (get('from_selection')) { $target_id = 0; } } if ($target_id != -1) { if ($target_id != 0) { if (!($target_task = Task::getEditableById($target_id))) { $PH->abortWarning(__("insufficient rights")); } ### get path of target to check for cycles ### $parent_tasks = $target_task->getFolder(); $parent_tasks[] = $target_task; } else { $parent_tasks = array(); } $count = 0; foreach ($file_ids as $id) { if ($file = File::getEditableById($id)) { $file->parent_item = $target_id; $file->update(); } else { $PH->messages[] = sprintf(__("Can not edit file %s"), $file->name); } } ### return to from-page? ### if (!$PH->showFromPage()) { $PH->show('home'); } exit; } #else if($target_id != -1) { # $PH->abortWarning(__("insufficient rights to edit any of the selected items")); #} /** * build page folder lists... */ ### get project #### if (!($file = File::getVisibleById($file_ids[0]))) { $PH->abortWarning("could not get file", ERROR_BUG); } if (!($project = Project::getVisibleById($file->project))) { $PH->abortWarning("file without project?", ERROR_BUG); } $page = new Page(array('use_jscalendar' => false, 'autofocus_field' => 'company_name')); $page->cur_tab = 'projects'; $page->type = __("Edit files"); $page->title = "{$project->name}"; $page->title_minor = __("Select folder to move files into"); $page->crumbs = build_project_crumbs($project); $page->options[] = new NaviOption(array('target_id' => 'filesMoveToFolder')); echo new PageHeader(); echo new PageContentOpen(); ### write files as hidden entry ### foreach ($file_ids as $id) { if ($file = File::getEditableById($id)) { echo "<input type=hidden name='files_{$id}_chk' value='1'>"; } } require_once confGet('DIR_STREBER') . 'lists/list_tasks.inc.php'; $list = new ListBlock_tasks(); $list->query_options['show_folders'] = true; #$list->query_options['folders_only']= true; $list->query_options['project'] = $project->id; $list->groupings = NULL; $list->block_functions = NULL; $list->id = 'folders'; $list->no_items_html = __('No folders available'); unset($list->columns['status']); unset($list->columns['date_start']); unset($list->columns['days_left']); unset($list->columns['created_by']); unset($list->columns['label']); unset($list->columns['project']); $list->functions = array(); $list->active_block_function = 'tree'; $list->print_automatic($project, NULL); echo __("(or select nothing to move to project root)") . "<br> "; echo "<input type=hidden name='from_selection' value='1'>"; # keep flag to ungroup files echo "<input type=hidden name='project' value='{$project->id}'>"; $button_name = __("Move items"); echo "<input class=button2 type=submit value='{$button_name}'>"; $PH->go_submit = 'filesMoveToFolder'; echo new PageContentClose(); echo new PageHtmlEnd(); }