public function componentIssueFields() { $this->items = array(); $this->showitems = true; $this->iscustom = false; $types = TBGDatatype::getTypes(); if (array_key_exists($this->type, $types)) { $this->items = call_user_func(array($types[$this->type], 'getAll')); } else { $customtype = TBGCustomDatatype::getByKey($this->type); $this->showitems = $customtype->hasCustomOptions(); $this->iscustom = true; if ($this->showitems) { $this->items = $customtype->getOptions(); } $this->customtype = $customtype; } }
/** * Add or delete a custom type * * @param TBGRequest $request */ public function runConfigureIssuefieldsCustomTypeAction(TBGRequest $request) { switch ($request->getParameter('mode')) { case 'add': if ($request->getParameter('name') != '') { try { $customtype = new TBGCustomDatatype(); $customtype->setName($request->getParameter('name')); $customtype->setItemdata($request->getParameter('label')); $customtype->setType($request->getParameter('field_type')); $customtype->save(); return $this->renderJSON(array('failed' => false, 'title' => TBGContext::getI18n()->__('The custom field was added'), 'content' => $this->getComponentHTML('issuefields_customtype', array('type_key' => $customtype->getKey(), 'type' => $customtype)))); } catch (Exception $e) { return $this->renderJSON(array('failed' => true, 'error' => $e->getMessage())); } } return $this->renderJSON(array('failed' => true, 'error' => TBGContext::getI18n()->__('Please provide a valid name'))); break; case 'update': if ($request->getParameter('name') != '') { $customtype = TBGCustomDatatype::getByKey($request->getParameter('type')); if ($customtype instanceof TBGCustomDatatype) { $customtype->setDescription($request->getParameter('description')); $customtype->setInstructions($request->getParameter('instructions')); $customtype->setName($request->getParameter('name')); $customtype->save(); return $this->renderJSON(array('failed' => false, 'title' => TBGContext::getI18n()->__('The custom field was updated'), 'description' => $customtype->getDescription(), 'instructions' => $customtype->getInstructions(), 'name' => $customtype->getName())); } return $this->renderJSON(array('failed' => true, 'error' => TBGContext::getI18n()->__('You need to provide a custom field key that already exists'))); } return $this->renderJSON(array('failed' => true, 'error' => TBGContext::getI18n()->__('Please provide a valid name'))); break; case 'delete': $customtype = TBGCustomDatatype::getByKey($request->getParameter('type')); if ($customtype instanceof TBGCustomDatatype) { $customtype->delete(); return $this->renderJSON(array('failed' => false, 'title' => TBGContext::getI18n()->__('The custom field was deleted'))); } return $this->renderJSON(array('failed' => true, 'error' => TBGContext::getI18n()->__('You need to provide a custom field key that already exists'))); break; } }
/** * Return an array specifying visibility, requirement and choices for fields in issues * * @param integer $issue_type * @param boolean $reportable[optional] Whether to only include fields that can be reported * * @return array */ protected function _getFieldsArray($issue_type, $reportable = true) { $issue_type = is_object($issue_type) ? $issue_type->getID() : $issue_type; if (!isset($this->_fieldsarrays[$issue_type][(int) $reportable])) { $retval = array(); $res = B2DB::getTable('TBGIssueFieldsTable')->getBySchemeIDandIssuetypeID($this->getIssuetypeScheme()->getID(), $issue_type); if ($res) { $builtin_types = TBGDatatype::getAvailableFields(true); while ($row = $res->getNextRow()) { if (!$reportable || (bool) $row->get(TBGIssueFieldsTable::REPORTABLE) == true) { if ($reportable) { if (in_array($row->get(TBGIssueFieldsTable::FIELD_KEY), $builtin_types) && (!$this->fieldPermissionCheck($row->get(TBGIssueFieldsTable::FIELD_KEY), $reportable) && !($row->get(TBGIssueFieldsTable::REQUIRED) && $reportable))) { continue; } elseif (!in_array($row->get(TBGIssueFieldsTable::FIELD_KEY), $builtin_types) && (!$this->fieldPermissionCheck($row->get(TBGIssueFieldsTable::FIELD_KEY), $reportable, true) && !($row->get(TBGIssueFieldsTable::REQUIRED) && $reportable))) { continue; } } $field_key = $row->get(TBGIssueFieldsTable::FIELD_KEY); $retval[$field_key] = array('required' => (bool) $row->get(TBGIssueFieldsTable::REQUIRED), 'additional' => (bool) $row->get(TBGIssueFieldsTable::ADDITIONAL)); if (!in_array($field_key, $builtin_types)) { $retval[$field_key]['custom'] = true; $custom_type = TBGCustomDatatype::getByKey($field_key); if ($custom_type instanceof TBGCustomDatatype) { $retval[$field_key]['custom_type'] = $custom_type->getType(); } else { unset($retval[$field_key]); } } } } if (array_key_exists('user_pain', $retval)) { $retval['pain_bug_type'] = array('required' => $retval['user_pain']['required']); $retval['pain_likelihood'] = array('required' => $retval['user_pain']['required']); $retval['pain_effect'] = array('required' => $retval['user_pain']['required']); } if ($reportable) { foreach ($retval as $key => $return_details) { if ($key == 'edition' || array_key_exists('custom', $return_details) && $return_details['custom'] && in_array($return_details['custom_type'], array(TBGCustomDatatype::EDITIONS_LIST, TBGCustomDatatype::EDITIONS_CHOICE))) { $retval[$key]['values'] = array(); $retval[$key]['values'][''] = TBGContext::getI18n()->__('None'); foreach ($this->getEditions() as $edition) { $retval[$key]['values'][$edition->getID()] = $edition->getName(); } if (!$this->isEditionsEnabled() || empty($retval[$key]['values'])) { if (!$retval[$key]['required']) { unset($retval[$key]); } else { unset($retval[$key]['values']); } } if (array_key_exists($key, $retval) && array_key_exists('values', $retval[$key])) { asort($retval[$key]['values'], SORT_STRING); } } elseif ($key == 'status' || array_key_exists('custom', $return_details) && $return_details['custom'] && in_array($return_details['custom_type'], array(TBGCustomDatatype::EDITIONS_LIST, TBGCustomDatatype::STATUS_CHOICE))) { $retval[$key]['values'] = array(); foreach (TBGStatus::getAll() as $status) { $retval[$key]['values'][$status->getID()] = $status->getName(); } if (empty($retval[$key]['values'])) { if (!$retval[$key]['required']) { unset($retval[$key]); } else { unset($retval[$key]['values']); } } if (array_key_exists($key, $retval) && array_key_exists('values', $retval[$key])) { asort($retval[$key]['values'], SORT_STRING); } } elseif ($key == 'component' || array_key_exists('custom', $return_details) && $return_details['custom'] && in_array($return_details['custom_type'], array(TBGCustomDatatype::COMPONENTS_LIST, TBGCustomDatatype::COMPONENTS_CHOICE))) { $retval[$key]['values'] = array(); $retval[$key]['values'][''] = TBGContext::getI18n()->__('None'); foreach ($this->getComponents() as $component) { $retval[$key]['values'][$component->getID()] = $component->getName(); } if (!$this->isComponentsEnabled() || empty($retval[$key]['values'])) { if (!$retval[$key]['required']) { unset($retval[$key]); } else { unset($retval[$key]['values']); } } if (array_key_exists($key, $retval) && array_key_exists('values', $retval[$key])) { asort($retval[$key]['values'], SORT_STRING); } } elseif ($key == 'build' || array_key_exists('custom', $return_details) && $return_details['custom'] && in_array($return_details['custom_type'], array(TBGCustomDatatype::RELEASES_LIST, TBGCustomDatatype::RELEASES_CHOICE))) { $retval[$key]['values'] = array(); $retval[$key]['values'][''] = TBGContext::getI18n()->__('None'); foreach ($this->getBuilds() as $build) { $retval[$key]['values'][$build->getID()] = $build->getName() . ' (' . $build->getVersion() . ')'; } if (!$this->isBuildsEnabled() || empty($retval[$key]['values'])) { if (!$retval[$key]['required']) { unset($retval[$key]); } else { unset($retval[$key]['values']); } } } } } } $this->_fieldsarrays[$issue_type][(int) $reportable] = $retval; } return $this->_fieldsarrays[$issue_type][(int) $reportable]; }
case 'estimated_time': echo __("You don't have access to estimate the issue"); break; case 'spent_time': echo __("You don't have access to specify time already spent working on the issue"); break; case 'percent_complete': echo __("You don't have access to specify how many percent complete the issue is"); break; } ?> <?php } else { ?> <?php echo __('You don\'t have access to enter "%field_name%"', array('%field_name%' => TBGCustomDatatype::getByKey($key)->getDescription())); ?> <?php } ?> </li> <?php } else { ?> <li><?php echo $p_error; ?> </li> <?php } ?>
/** * * @param \b2db\Criteria $crit * @param array|TBGSearchFilter $filters * @param \b2db\Criterion $ctn * @return null */ public function addToCriteria($crit, $filters, $ctn = null) { $filter_key = $this->getFilterKey(); if (in_array($this['operator'], array('=', '!=', '<=', '>=', '<', '>'))) { if ($filter_key == 'text') { if ($this['value'] != '') { $searchterm = mb_strpos($this['value'], '%') !== false ? $this['value'] : "%{$this['value']}%"; if ($this['operator'] == '=') { if ($ctn === null) { $ctn = $crit->returnCriterion(TBGIssuesTable::TITLE, $searchterm, Criteria::DB_LIKE); } $ctn->addOr(TBGIssuesTable::DESCRIPTION, $searchterm, Criteria::DB_LIKE); $ctn->addOr(TBGIssuesTable::REPRODUCTION_STEPS, $searchterm, Criteria::DB_LIKE); $ctn->addOr(TBGIssueCustomFieldsTable::OPTION_VALUE, $searchterm, Criteria::DB_LIKE); } else { if ($ctn === null) { $ctn = $crit->returnCriterion(TBGIssuesTable::TITLE, $searchterm, Criteria::DB_NOT_LIKE); } $ctn->addWhere(TBGIssuesTable::DESCRIPTION, $searchterm, Criteria::DB_NOT_LIKE); $ctn->addWhere(TBGIssuesTable::REPRODUCTION_STEPS, $searchterm, Criteria::DB_NOT_LIKE); $ctn->addOr(TBGIssueCustomFieldsTable::OPTION_VALUE, $searchterm, Criteria::DB_NOT_LIKE); } return $ctn; } } elseif (in_array($filter_key, self::getValidSearchFilters())) { if ($filter_key == 'subprojects') { if (TBGContext::isProjectContext()) { if ($ctn === null) { $ctn = $crit->returnCriterion(TBGIssuesTable::PROJECT_ID, TBGContext::getCurrentProject()->getID()); } if ($this->hasValue()) { foreach ($this->getValues() as $value) { switch ($value) { case 'all': $subprojects = TBGProject::getIncludingAllSubprojectsAsArray(TBGContext::getCurrentProject()); foreach ($subprojects as $subproject) { if ($subproject->getID() == TBGContext::getCurrentProject()->getID()) { continue; } $ctn->addOr(TBGIssuesTable::PROJECT_ID, $subproject->getID()); } break; case 'none': case '': break; default: $ctn->addOr(TBGIssuesTable::PROJECT_ID, (int) $value); break; } } } return $ctn; } } elseif (in_array($filter_key, array('build', 'edition', 'component'))) { switch ($filter_key) { case 'component': $tbl = TBGIssueAffectsComponentTable::getTable(); $fk = TBGIssueAffectsComponentTable::ISSUE; break; case 'edition': $tbl = TBGIssueAffectsEditionTable::getTable(); $fk = TBGIssueAffectsEditionTable::ISSUE; break; case 'build': $tbl = TBGIssueAffectsBuildTable::getTable(); $fk = TBGIssueAffectsBuildTable::ISSUE; break; } $crit->addJoin($tbl, $fk, TBGIssuesTable::ID, array(array($tbl->getB2DBAlias() . '.' . $filter_key, $this->getValues())), \b2db\Criteria::DB_INNER_JOIN); return null; } else { if ($filter_key == 'project_id' && in_array('subprojects', $filters)) { return null; } $values = $this->getValues(); $num_values = 0; if ($filter_key == 'status') { if ($this->hasValue('open')) { $c = $crit->returnCriterion(TBGIssuesTable::STATE, TBGIssue::STATE_OPEN); $num_values++; } if ($this->hasValue('closed')) { $num_values++; if (isset($c)) { $c->addWhere(TBGIssuesTable::STATE, TBGIssue::STATE_CLOSED); } else { $c = $crit->returnCriterion(TBGIssuesTable::STATE, TBGIssue::STATE_CLOSED); } } if (isset($c)) { if (count($values) == $num_values) { return $c; } else { $crit->addWhere($c); } } } $dbname = TBGIssuesTable::getTable()->getB2DBName(); foreach ($values as $value) { $operator = $this['operator']; $or = true; if ($filter_key == 'status' && in_array($value, array('open', 'closed'))) { continue; } else { $field = $dbname . '.' . $filter_key; if ($operator == '!=' || in_array($filter_key, array('posted', 'last_updated'))) { $or = false; } } if ($ctn === null) { $ctn = $crit->returnCriterion($field, $value, urldecode($operator)); } elseif ($or) { $ctn->addOr($field, $value, urldecode($operator)); } else { $ctn->addWhere($field, $value, urldecode($operator)); } } return $ctn; } } elseif (TBGCustomDatatype::doesKeyExist($filter_key)) { $customdatatype = TBGCustomDatatype::getByKey($filter_key); if (in_array($this->getFilterType(), TBGCustomDatatype::getInternalChoiceFieldsAsArray())) { $tbl = clone TBGIssueCustomFieldsTable::getTable(); $crit->addJoin($tbl, TBGIssueCustomFieldsTable::ISSUE_ID, TBGIssuesTable::ID, array(array($tbl->getB2DBAlias() . '.customfields_id', $customdatatype->getID()), array($tbl->getB2DBAlias() . '.customfieldoption_id', $this->getValues())), \b2db\Criteria::DB_INNER_JOIN); return null; } else { foreach ($this->getValues() as $value) { if ($customdatatype->hasCustomOptions()) { if ($ctn === null) { $ctn = $crit->returnCriterion(TBGIssueCustomFieldsTable::CUSTOMFIELDS_ID, $customdatatype->getID()); $ctn->addWhere(TBGIssueCustomFieldsTable::CUSTOMFIELDOPTION_ID, $value, $this['operator']); } else { $ctn->addOr(TBGIssueCustomFieldsTable::CUSTOMFIELDOPTION_ID, $value, $this['operator']); } } else { if ($ctn === null) { $ctn = $crit->returnCriterion(TBGIssueCustomFieldsTable::CUSTOMFIELDS_ID, $customdatatype->getID()); $ctn->addWhere(TBGIssueCustomFieldsTable::OPTION_VALUE, $value, $this['operator']); } else { $ctn->addOr(TBGIssueCustomFieldsTable::OPTION_VALUE, $value, $this['operator']); } } } return $ctn; } } } }
} break; case TBGLogTable::LOG_ISSUE_POSTED: echo image_tag('icon_user.png'); if ($item->hasChangeDetails()) { $previous_value = $item->getPreviousValue() ? ($old_item = TBGContext::factory()->TBGUser($item->getPreviousValue())) ? __($old_item->getName()) : __('Unknown') : __('Not determined'); $new_value = $item->getCurrentValue() ? ($new_item = TBGContext::factory()->TBGUser($item->getCurrentValue())) ? __($new_item->getName()) : __('Unknown') : __('Not determined'); echo __("Posted by changed: %previous_value => %new_value", array('%previous_value' => '<strong>' . $previous_value . '</strong>', '%new_value' => '<strong>' . $new_value . '</strong>')); } break; case TBGLogTable::LOG_ISSUE_CUSTOMFIELD_CHANGED: echo image_tag('icon_customdatatype.png'); if ($item->hasChangeDetails()) { $key_data = explode(':', $item->getText()); $key = $key_data[0]; $customdatatype = TBGCustomDatatype::getByKey($key); if ($customdatatype instanceof TBGCustomDatatype) { $old_value = $item->getPreviousValue(); $new_value = $item->getCurrentValue(); switch ($customdatatype->getType()) { case TBGCustomDatatype::INPUT_TEXT: case TBGCustomDatatype::INPUT_TEXTAREA_SMALL: case TBGCustomDatatype::INPUT_TEXTAREA_MAIN: break; case TBGCustomDatatype::DATE_PICKER: $old_value = $old_value != null ? date('Y-m-d', (int) $old_value) : TBGContext::getI18n()->__('Not determined'); $new_value = $new_value != null ? date('Y-m-d', (int) $new_value) : TBGContext::getI18n()->__('Not determined'); break; case TBGCustomDatatype::EDITIONS_CHOICE: case TBGCustomDatatype::COMPONENTS_CHOICE: case TBGCustomDatatype::RELEASES_CHOICE:
/** * Reverts an issue field back to the original value * * @param TBGRequest $request */ public function runIssueRevertField(TBGRequest $request) { if ($issue_id = $request['issue_id']) { try { $issue = TBGContext::factory()->TBGIssue($issue_id); } catch (Exception $e) { $this->getResponse()->setHttpStatus(400); return $this->renderText('fail'); } } else { $this->getResponse()->setHttpStatus(400); return $this->renderText('no issue'); } $field = null; TBGContext::loadLibrary('common'); switch ($request['field']) { case 'description': $issue->revertDescription(); $issue->revertDescription_Syntax(); $field = array('id' => (int) ($issue->getDescription() != ''), 'name' => $issue->getParsedDescription(array('issue' => $issue)), 'form_value' => $issue->getDescription()); break; case 'reproduction_steps': $issue->revertReproduction_Steps(); $issue->revertReproduction_Steps_Syntax(); $field = array('id' => (int) ($issue->getReproductionSteps() != ''), 'name' => $issue->getParsedReproductionSteps(array('issue' => $issue)), 'form_value' => $issue->getReproductionSteps()); break; case 'title': $issue->revertTitle(); $field = array('id' => 1, 'name' => strip_tags($issue->getTitle())); break; case 'category': $issue->revertCategory(); $field = $issue->getCategory() instanceof TBGCategory ? array('id' => $issue->getCategory()->getID(), 'name' => $issue->getCategory()->getName()) : array('id' => 0); break; case 'resolution': $issue->revertResolution(); $field = $issue->getResolution() instanceof TBGResolution ? array('id' => $issue->getResolution()->getID(), 'name' => $issue->getResolution()->getName()) : array('id' => 0); break; case 'severity': $issue->revertSeverity(); $field = $issue->getSeverity() instanceof TBGSeverity ? array('id' => $issue->getSeverity()->getID(), 'name' => $issue->getSeverity()->getName()) : array('id' => 0); break; case 'reproducability': $issue->revertReproducability(); $field = $issue->getReproducability() instanceof TBGReproducability ? array('id' => $issue->getReproducability()->getID(), 'name' => $issue->getReproducability()->getName()) : array('id' => 0); break; case 'priority': $issue->revertPriority(); $field = $issue->getPriority() instanceof TBGPriority ? array('id' => $issue->getPriority()->getID(), 'name' => $issue->getPriority()->getName()) : array('id' => 0); break; case 'percent_complete': $issue->revertPercentCompleted(); $field = $issue->getPercentCompleted(); break; case 'status': $issue->revertStatus(); $field = $issue->getStatus() instanceof TBGStatus ? array('id' => $issue->getStatus()->getID(), 'name' => $issue->getStatus()->getName(), 'color' => $issue->getStatus()->getColor()) : array('id' => 0); break; case 'pain_bug_type': $issue->revertPainBugType(); $field = $issue->hasPainBugType() ? array('id' => $issue->getPainBugType(), 'name' => $issue->getPainBugTypeLabel(), 'user_pain' => $issue->getUserPain()) : array('id' => 0, 'user_pain' => $issue->getUserPain()); break; case 'pain_likelihood': $issue->revertPainLikelihood(); $field = $issue->hasPainLikelihood() ? array('id' => $issue->getPainLikelihood(), 'name' => $issue->getPainLikelihoodLabel(), 'user_pain' => $issue->getUserPain()) : array('id' => 0, 'user_pain' => $issue->getUserPain()); break; case 'pain_effect': $issue->revertPainEffect(); $field = $issue->hasPainEffect() ? array('id' => $issue->getPainEffect(), 'name' => $issue->getPainEffectLabel(), 'user_pain' => $issue->getUserPain()) : array('id' => 0, 'user_pain' => $issue->getUserPain()); break; case 'issuetype': $issue->revertIssuetype(); $field = $issue->getIssuetype() instanceof TBGIssuetype ? array('id' => $issue->getIssuetype()->getID(), 'name' => $issue->getIssuetype()->getName(), 'src' => htmlspecialchars(TBGContext::getTBGPath() . 'iconsets/' . TBGSettings::getThemeName() . '/' . $issue->getIssuetype()->getIcon() . '_small.png')) : array('id' => 0); $visible_fields = $issue->getIssuetype() instanceof TBGIssuetype ? $issue->getProject()->getVisibleFieldsArray($issue->getIssuetype()->getID()) : array(); return $this->renderJSON(array('ok' => true, 'issue_id' => $issue->getID(), 'field' => $field, 'visible_fields' => $visible_fields)); break; case 'milestone': $issue->revertMilestone(); $field = $issue->getMilestone() instanceof TBGMilestone ? array('id' => $issue->getMilestone()->getID(), 'name' => $issue->getMilestone()->getName()) : array('id' => 0); break; case 'estimated_time': $issue->revertEstimatedTime(); return $this->renderJSON(array('ok' => true, 'issue_id' => $issue->getID(), 'field' => $issue->hasEstimatedTime() ? array('id' => 1, 'name' => TBGIssue::getFormattedTime($issue->getEstimatedTime())) : array('id' => 0), 'values' => $issue->getEstimatedTime())); break; case 'spent_time': $issue->revertSpentTime(); return $this->renderJSON(array('ok' => true, 'issue_id' => $issue->getID(), 'field' => $issue->hasSpentTime() ? array('id' => 1, 'name' => TBGIssue::getFormattedTime($issue->getSpentTime())) : array('id' => 0), 'values' => $issue->getSpentTime())); break; case 'owned_by': $issue->revertOwner(); return $this->renderJSON(array('changed' => $issue->isOwnerChanged(), 'field' => $issue->isOwned() ? array('id' => $issue->getOwner()->getID(), 'name' => $issue->getOwner() instanceof TBGUser ? $this->getComponentHTML('main/userdropdown', array('user' => $issue->getOwner())) : $this->getComponentHTML('main/teamdropdown', array('team' => $issue->getOwner()))) : array('id' => 0))); break; case 'assigned_to': $issue->revertAssignee(); return $this->renderJSON(array('changed' => $issue->isAssigneeChanged(), 'field' => $issue->isAssigned() ? array('id' => $issue->getAssignee()->getID(), 'name' => $issue->getAssignee() instanceof TBGUser ? $this->getComponentHTML('main/userdropdown', array('user' => $issue->getAssignee())) : $this->getComponentHTML('main/teamdropdown', array('team' => $issue->getAssignee()))) : array('id' => 0))); break; case 'posted_by': $issue->revertPostedBy(); return $this->renderJSON(array('changed' => $issue->isPostedByChanged(), 'field' => array('id' => $issue->getPostedByID(), 'name' => $this->getComponentHTML('main/userdropdown', array('user' => $issue->getPostedBy()))))); break; default: if ($customdatatype = TBGCustomDatatype::getByKey($request['field'])) { $key = $customdatatype->getKey(); $revert_methodname = "revertCustomfield{$key}"; $issue->{$revert_methodname}(); if ($customdatatype->hasCustomOptions()) { $field = $issue->getCustomField($key) instanceof TBGCustomDatatypeOption ? array('value' => $issue->getCustomField($key)->getID(), 'name' => $issue->getCustomField($key)->getName()) : array('id' => 0); } else { switch ($customdatatype->getType()) { case TBGCustomDatatype::INPUT_TEXTAREA_MAIN: case TBGCustomDatatype::INPUT_TEXTAREA_SMALL: $field = $issue->getCustomField($key) != '' ? array('value' => $key, 'name' => tbg_parse_text($issue->getCustomField($key))) : array('id' => 0); break; default: $field = $issue->getCustomField($key) != '' ? array('value' => $key, 'name' => $issue->getCustomField($key)) : array('id' => 0); break; } } } break; } if ($field !== null) { return $this->renderJSON(array('ok' => true, 'issue_id' => $issue->getID(), 'field' => $field)); } else { $this->getResponse()->setHttpStatus(400); return $this->renderJSON(array('error' => TBGContext::getI18n()->__('No valid field specified (%field)', array('%field' => $request['field'])))); } }
><?php echo __('Closed'); ?> </option> </select> <?php $show_button = true; ?> <?php } ?> <?php } else { ?> <?php $customdatatype = TBGCustomDatatype::getByKey($filter); ?> <label for="filter_<?php echo $filter; ?> _<?php echo $key; ?> "><?php echo __($customdatatype->getDescription()); ?> </label> <select name="filters[<?php echo $filter; ?> ][<?php
protected function _processChanges() { $related_issues_to_save = array(); $changed_properties = $this->_getChangedProperties(); if (count($changed_properties)) { $is_saved_estimated = false; $is_saved_spent = false; $is_saved_assignee = false; $is_saved_owner = false; foreach ($changed_properties as $property => $value) { $compare_value = is_object($this->{$property}) ? $this->{$property}->getID() : $this->{$property}; $original_value = $value['original_value']; if ($original_value != $compare_value) { switch ($property) { case '_title': $this->addLogEntry(TBGLogTable::LOG_ISSUE_UPDATE_TITLE, TBGContext::getI18n()->__("Title updated"), $original_value, $compare_value); break; case '_description': $this->addLogEntry(TBGLogTable::LOG_ISSUE_UPDATE_DESCRIPTION, TBGContext::getI18n()->__("Description updated"), $original_value, $compare_value); break; case '_reproduction_steps': $this->addLogEntry(TBGLogTable::LOG_ISSUE_UPDATE_REPRODUCTIONSTEPS, TBGContext::getI18n()->__("Reproduction steps updated"), $original_value, $compare_value); break; case '_category': if ($original_value != 0) { $old_name = ($old_item = TBGContext::factory()->TBGCategory($original_value)) ? $old_item->getName() : TBGContext::getI18n()->__('Not determined'); } else { $old_name = TBGContext::getI18n()->__('Not determined'); } $new_name = $this->getCategory() instanceof TBGDatatype ? $this->getCategory()->getName() : TBGContext::getI18n()->__('Not determined'); $this->addLogEntry(TBGLogTable::LOG_ISSUE_CATEGORY, $old_name . ' ⇒ ' . $new_name, $original_value, $compare_value); break; case '_pain_bug_type': if ($original_value != 0) { $old_name = ($old_item = self::getPainTypesOrLabel('pain_bug_type', $original_value)) ? $old_item : TBGContext::getI18n()->__('Not determined'); } else { $old_name = TBGContext::getI18n()->__('Not determined'); } $new_name = ($new_item = self::getPainTypesOrLabel('pain_bug_type', $value['current_value'])) ? $new_item : TBGContext::getI18n()->__('Not determined'); $this->addLogEntry(TBGLogTable::LOG_ISSUE_PAIN_BUG_TYPE, $old_name . ' ⇒ ' . $new_name, $original_value, $compare_value); break; case '_pain_effect': if ($original_value != 0) { $old_name = ($old_item = self::getPainTypesOrLabel('pain_effect', $original_value)) ? $old_item : TBGContext::getI18n()->__('Not determined'); } else { $old_name = TBGContext::getI18n()->__('Not determined'); } $new_name = ($new_item = self::getPainTypesOrLabel('pain_effect', $value['current_value'])) ? $new_item : TBGContext::getI18n()->__('Not determined'); $this->addLogEntry(TBGLogTable::LOG_ISSUE_PAIN_EFFECT, $old_name . ' ⇒ ' . $new_name, $original_value, $compare_value); break; case '_pain_likelihood': if ($original_value != 0) { $old_name = ($old_item = self::getPainTypesOrLabel('pain_likelihood', $original_value)) ? $old_item : TBGContext::getI18n()->__('Not determined'); } else { $old_name = TBGContext::getI18n()->__('Not determined'); } $new_name = ($new_item = self::getPainTypesOrLabel('pain_likelihood', $value['current_value'])) ? $new_item : TBGContext::getI18n()->__('Not determined'); $this->addLogEntry(TBGLogTable::LOG_ISSUE_PAIN_LIKELIHOOD, $old_name . ' ⇒ ' . $new_name, $original_value, $compare_value); break; case '_user_pain': $this->addLogEntry(TBGLogTable::LOG_ISSUE_PAIN_CALCULATED, $original_value . ' ⇒ ' . $value['current_value']); break; case '_status': if ($original_value != 0) { $old_name = ($old_item = TBGContext::factory()->TBGStatus($original_value)) ? $old_item->getName() : TBGContext::getI18n()->__('Unknown'); } else { $old_name = TBGContext::getI18n()->__('Not determined'); } $new_name = $this->getStatus() instanceof TBGDatatype ? $this->getStatus()->getName() : TBGContext::getI18n()->__('Not determined'); $this->addLogEntry(TBGLogTable::LOG_ISSUE_STATUS, $old_name . ' ⇒ ' . $new_name, $original_value, $compare_value); break; case '_reproducability': if ($original_value != 0) { $old_name = ($old_item = TBGContext::factory()->TBGReproducability($original_value)) ? $old_item->getName() : TBGContext::getI18n()->__('Unknown'); } else { $old_name = TBGContext::getI18n()->__('Not determined'); } $new_name = $this->getReproducability() instanceof TBGDatatype ? $this->getReproducability()->getName() : TBGContext::getI18n()->__('Not determined'); $this->addLogEntry(TBGLogTable::LOG_ISSUE_REPRODUCABILITY, $old_name . ' ⇒ ' . $new_name, $original_value, $compare_value); break; case '_priority': if ($original_value != 0) { $old_name = ($old_item = TBGContext::factory()->TBGPriority($original_value)) ? $old_item->getName() : TBGContext::getI18n()->__('Unknown'); } else { $old_name = TBGContext::getI18n()->__('Not determined'); } $new_name = $this->getPriority() instanceof TBGDatatype ? $this->getPriority()->getName() : TBGContext::getI18n()->__('Not determined'); $this->addLogEntry(TBGLogTable::LOG_ISSUE_PRIORITY, $old_name . ' ⇒ ' . $new_name, $original_value, $compare_value); break; case '_assignee_team': case '_assignee_user': if (!$is_saved_assignee) { $new_name = $this->getAssignee() instanceof TBGIdentifiable ? $this->getAssignee()->getName() : TBGContext::getI18n()->__('Not assigned'); if ($this->getAssignee() instanceof TBGUser) { $this->startWorkingOnIssue($this->getAssignee()); } $this->addLogEntry(TBGLogTable::LOG_ISSUE_ASSIGNED, $new_name); $is_saved_assignee = true; } break; case '_posted_by': $old_identifiable = $original_value ? TBGContext::factory()->TBGUser($original_value) : TBGContext::getI18n()->__('Unknown'); $old_name = $old_identifiable instanceof TBGUser ? $old_identifiable->getName() : TBGContext::getI18n()->__('Unknown'); $new_name = $this->getPostedBy()->getName(); $this->addLogEntry(TBGLogTable::LOG_ISSUE_POSTED, $old_name . ' ⇒ ' . $new_name, $original_value, $compare_value); break; case '_being_worked_on_by_user': if ($original_value != 0) { $old_identifiable = TBGContext::factory()->TBGUser($original_value); $old_name = $old_identifiable instanceof TBGUser ? $old_identifiable->getName() : TBGContext::getI18n()->__('Unknown'); } else { $old_name = TBGContext::getI18n()->__('Not being worked on'); } $new_name = $this->getUserWorkingOnIssue() instanceof TBGUser ? $this->getUserWorkingOnIssue()->getName() : TBGContext::getI18n()->__('Not being worked on'); $this->addLogEntry(TBGLogTable::LOG_ISSUE_USERS, $old_name . ' ⇒ ' . $new_name, $original_value, $compare_value); break; case '_owner_team': case '_owner_user': if (!$is_saved_owner) { $new_name = $this->getOwner() instanceof TBGIdentifiable ? $this->getOwner()->getName() : TBGContext::getI18n()->__('Not owned by anyone'); $this->addLogEntry(TBGLogTable::LOG_ISSUE_OWNED, $new_name); $is_saved_owner = true; } break; case '_percent_complete': $this->addLogEntry(TBGLogTable::LOG_ISSUE_PERCENT, $original_value . '% ⇒ ' . $this->getPercentCompleted() . '', $original_value, $compare_value); break; case '_resolution': if ($original_value != 0) { $old_name = ($old_item = TBGContext::factory()->TBGResolution($original_value)) ? $old_item->getName() : TBGContext::getI18n()->__('Unknown'); } else { $old_name = TBGContext::getI18n()->__('Not determined'); } $new_name = $this->getResolution() instanceof TBGDatatype ? $this->getResolution()->getName() : TBGContext::getI18n()->__('Not determined'); $this->addLogEntry(TBGLogTable::LOG_ISSUE_RESOLUTION, $old_name . ' ⇒ ' . $new_name, $original_value, $compare_value); break; case '_severity': if ($original_value != 0) { $old_name = ($old_item = TBGContext::factory()->TBGSeverity($original_value)) ? $old_item->getName() : TBGContext::getI18n()->__('Unknown'); } else { $old_name = TBGContext::getI18n()->__('Not determined'); } $new_name = $this->getSeverity() instanceof TBGDatatype ? $this->getSeverity()->getName() : TBGContext::getI18n()->__('Not determined'); $this->addLogEntry(TBGLogTable::LOG_ISSUE_SEVERITY, $old_name . ' ⇒ ' . $new_name, $original_value, $compare_value); break; case '_milestone': if ($original_value != 0) { $old_name = ($old_item = TBGContext::factory()->TBGMilestone($original_value)) ? $old_item->getName() : TBGContext::getI18n()->__('Not determined'); } else { $old_name = TBGContext::getI18n()->__('Not determined'); } $new_name = $this->getMilestone() instanceof TBGMilestone ? $this->getMilestone()->getName() : TBGContext::getI18n()->__('Not determined'); $this->addLogEntry(TBGLogTable::LOG_ISSUE_MILESTONE, $old_name . ' ⇒ ' . $new_name, $original_value, $compare_value); $this->_milestone_order = 0; break; case '_issuetype': if ($original_value != 0) { $old_name = ($old_item = TBGContext::factory()->TBGIssuetype($original_value)) ? $old_item->getName() : TBGContext::getI18n()->__('Unknown'); } else { $old_name = TBGContext::getI18n()->__('Unknown'); } $new_name = $this->getIssuetype() instanceof TBGIssuetype ? $this->getIssuetype()->getName() : TBGContext::getI18n()->__('Unknown'); $this->addLogEntry(TBGLogTable::LOG_ISSUE_ISSUETYPE, $old_name . ' ⇒ ' . $new_name, $original_value, $compare_value); break; case '_estimated_months': case '_estimated_weeks': case '_estimated_days': case '_estimated_hours': case '_estimated_points': if (!$is_saved_estimated) { $old_time = array('months' => $this->getChangedPropertyOriginal('_estimated_months'), 'weeks' => $this->getChangedPropertyOriginal('_estimated_weeks'), 'days' => $this->getChangedPropertyOriginal('_estimated_days'), 'hours' => $this->getChangedPropertyOriginal('_estimated_hours'), 'points' => $this->getChangedPropertyOriginal('_estimated_points')); $old_formatted_time = array_sum($old_time) > 0 ? TBGIssue::getFormattedTime($old_time) : TBGContext::getI18n()->__('Not estimated'); $new_formatted_time = $this->hasEstimatedTime() ? TBGIssue::getFormattedTime($this->getEstimatedTime()) : TBGContext::getI18n()->__('Not estimated'); $this->addLogEntry(TBGLogTable::LOG_ISSUE_TIME_ESTIMATED, $old_formatted_time . ' ⇒ ' . $new_formatted_time, serialize($old_time), serialize($this->getEstimatedTime())); $is_saved_estimated = true; } break; case '_spent_months': case '_spent_weeks': case '_spent_days': case '_spent_hours': case '_spent_points': if (!$is_saved_spent) { $old_time = array('months' => $this->getChangedPropertyOriginal('_spent_months'), 'weeks' => $this->getChangedPropertyOriginal('_spent_weeks'), 'days' => $this->getChangedPropertyOriginal('_spent_days'), 'hours' => $this->getChangedPropertyOriginal('_spent_hours'), 'points' => $this->getChangedPropertyOriginal('_spent_points')); $old_formatted_time = array_sum($old_time) > 0 ? TBGIssue::getFormattedTime($old_time) : TBGContext::getI18n()->__('No time spent'); $new_formatted_time = $this->hasSpentTime() ? TBGIssue::getFormattedTime($this->getSpentTime()) : TBGContext::getI18n()->__('No time spent'); $this->addLogEntry(TBGLogTable::LOG_ISSUE_TIME_SPENT, $old_formatted_time . ' ⇒ ' . $new_formatted_time, serialize($old_time), serialize($this->getSpentTime())); $is_saved_spent = true; } break; case '_state': if ($this->isClosed()) { $this->addLogEntry(TBGLogTable::LOG_ISSUE_CLOSE); if ($this->getMilestone() instanceof TBGMilestone) { if ($this->getMilestone()->isSprint()) { if (!$this->getIssueType()->isTask()) { $this->setSpentPoints($this->getEstimatedPoints()); } else { if ($this->getSpentHours() < $this->getEstimatedHours()) { $this->setSpentHours($this->getEstimatedHours()); } foreach ($this->getParentIssues() as $parent_issue) { if ($parent_issue->checkTaskStates()) { $related_issues_to_save[$parent_issue->getID()] = true; } } } } $this->getMilestone()->updateStatus(); } } else { $this->addLogEntry(TBGLogTable::LOG_ISSUE_REOPEN); } break; case '_blocking': if ($this->isBlocking()) { $this->addLogEntry(TBGLogTable::LOG_ISSUE_BLOCKED); } else { $this->addLogEntry(TBGLogTable::LOG_ISSUE_UNBLOCKED); } break; default: if (mb_substr($property, 0, 12) == '_customfield') { $key = mb_substr($property, 12); $customdatatype = TBGCustomDatatype::getByKey($key); switch ($customdatatype->getType()) { case TBGCustomDatatype::INPUT_TEXT: $new_value = $this->getCustomField($key) != '' ? $this->getCustomField($key) : TBGContext::getI18n()->__('Unknown'); $this->addLogEntry(TBGLogTable::LOG_ISSUE_CUSTOMFIELD_CHANGED, $key . ': ' . $new_value, $original_value, $compare_value); break; case TBGCustomDatatype::INPUT_TEXTAREA_SMALL: case TBGCustomDatatype::INPUT_TEXTAREA_MAIN: $new_value = $this->getCustomField($key) != '' ? $this->getCustomField($key) : TBGContext::getI18n()->__('Unknown'); $this->addLogEntry(TBGLogTable::LOG_ISSUE_CUSTOMFIELD_CHANGED, $key . ': ' . $new_value, $original_value, $compare_value); break; case TBGCustomDatatype::EDITIONS_CHOICE: case TBGCustomDatatype::COMPONENTS_CHOICE: case TBGCustomDatatype::RELEASES_CHOICE: case TBGCustomDatatype::STATUS_CHOICE: $old_object = null; $new_object = null; try { switch ($customdatatype->getType()) { case TBGCustomDatatype::EDITIONS_CHOICE: $old_object = TBGContext::factory()->TBGEdition($original_value); break; case TBGCustomDatatype::COMPONENTS_CHOICE: $old_object = TBGContext::factory()->TBGComponent($original_value); break; case TBGCustomDatatype::RELEASES_CHOICE: $old_object = TBGContext::factory()->TBGBuild($original_value); break; case TBGCustomDatatype::STATUS_CHOICE: $old_object = TBGContext::factory()->TBGStatus($original_value); break; } } catch (Exception $e) { } try { switch ($customdatatype->getType()) { case TBGCustomDatatype::EDITIONS_CHOICE: $new_object = TBGContext::factory()->TBGEdition($this->getCustomField($key)); break; case TBGCustomDatatype::COMPONENTS_CHOICE: $new_object = TBGContext::factory()->TBGComponent($this->getCustomField($key)); break; case TBGCustomDatatype::RELEASES_CHOICE: $new_object = TBGContext::factory()->TBGBuild($this->getCustomField($key)); break; case TBGCustomDatatype::STATUS_CHOICE: $new_object = TBGContext::factory()->TBGStatus($this->getCustomField($key)); break; } } catch (Exception $e) { } $old_value = is_object($old_object) ? $old_object->getName() : TBGContext::getI18n()->__('Unknown'); $new_value = is_object($new_object) ? $new_object->getName() : TBGContext::getI18n()->__('Unknown'); $this->addLogEntry(TBGLogTable::LOG_ISSUE_CUSTOMFIELD_CHANGED, $key . ': ' . $old_value . ' ⇒ ' . $new_value, $original_value, $compare_value); break; default: $old_item = null; try { $old_item = $original_value ? new TBGCustomDatatypeOption($original_value) : null; } catch (Exception $e) { } $old_value = $old_item instanceof TBGCustomDatatypeOption ? $old_item->getName() : TBGContext::getI18n()->__('Unknown'); $new_value = $this->getCustomField($key) instanceof TBGCustomDatatypeOption ? $this->getCustomField($key)->getName() : TBGContext::getI18n()->__('Unknown'); $this->addLogEntry(TBGLogTable::LOG_ISSUE_CUSTOMFIELD_CHANGED, $key . ': ' . $old_value . ' ⇒ ' . $new_value, $original_value, $compare_value); break; } } break; } } } if ($is_saved_estimated) { TBGIssueEstimates::getTable()->saveEstimate($this->getID(), $this->_estimated_months, $this->_estimated_weeks, $this->_estimated_days, $this->_estimated_hours, $this->_estimated_points); } } return $related_issues_to_save; }
/** * Save changes made to the issue since last time * * @return boolean */ public function _preSave($is_new) { if ($is_new) { if (!$this->_issue_no) { $this->_issue_no = TBGIssuesTable::getTable()->getNextIssueNumberForProductID($this->getProject()->getID()); } if (!$this->_posted) { $this->_posted = NOW; } if (!$this->_last_updated) { $this->_last_updated = NOW; } if (!$this->_posted_by) { $this->_posted_by = TBGContext::getUser(); } $step = $this->getProject()->getWorkflowScheme()->getWorkflowForIssuetype($this->getIssueType())->getFirstStep(); $step->applyToIssue($this); return; } $this->_last_updated = NOW; $comment_lines = array(); $related_issues_to_save = array(); $is_saved_estimated = false; $is_saved_spent = false; $is_saved_assignee = false; $is_saved_owner = false; $changed_properties = $this->_getChangedProperties(); if (count($changed_properties) == 0) { return false; } foreach ($changed_properties as $property => $value) { $compare_value = is_object($this->{$property}) ? $this->{$property}->getID() : $this->{$property}; if ($value['original_value'] != $compare_value) { switch ($property) { case '_title': $this->addLogEntry(TBGLogTable::LOG_ISSUE_UPDATE, TBGContext::getI18n()->__("Title updated")); $comment_lines[] = TBGContext::getI18n()->__("This issue's title has been changed"); break; case '_description': $this->addLogEntry(TBGLogTable::LOG_ISSUE_UPDATE, TBGContext::getI18n()->__("Description updated")); $comment_lines[] = TBGContext::getI18n()->__("This issue's description has been changed"); break; case '_reproduction_steps': $this->addLogEntry(TBGLogTable::LOG_ISSUE_REPRODUCABILITY, TBGContext::getI18n()->__("Reproduction steps updated")); $comment_lines[] = TBGContext::getI18n()->__("This issue's reproduction steps has been changed"); break; case '_category': if ($value['original_value'] != 0) { $old_name = ($old_item = TBGContext::factory()->TBGCategory($value['original_value'])) ? $old_item->getName() : TBGContext::getI18n()->__('Not determined'); } else { $old_name = TBGContext::getI18n()->__('Not determined'); } $new_name = $this->getCategory() instanceof TBGDatatype ? $this->getCategory()->getName() : TBGContext::getI18n()->__('Not determined'); $this->addLogEntry(TBGLogTable::LOG_ISSUE_CATEGORY, $old_name . ' ⇒ ' . $new_name); $comment_lines[] = TBGContext::getI18n()->__("The category has been updated, from '''%previous_category%''' to '''%new_category%'''.", array('%previous_category%' => $old_name, '%new_category%' => $new_name)); break; case '_pain_bug_type': if ($value['original_value'] != 0) { $old_name = ($old_item = self::getPainTypesOrLabel('pain_bug_type', $value['original_value'])) ? $old_item : TBGContext::getI18n()->__('Not determined'); } else { $old_name = TBGContext::getI18n()->__('Not determined'); } $new_name = ($new_item = self::getPainTypesOrLabel('pain_bug_type', $value['current_value'])) ? $new_item : TBGContext::getI18n()->__('Not determined'); $this->addLogEntry(TBGLogTable::LOG_ISSUE_PAIN_BUG_TYPE, $old_name . ' ⇒ ' . $new_name); $comment_lines[] = TBGContext::getI18n()->__("The triaging criteria 'bug type' has been updated, from '''%previous_name%''' to '''%new_name%'''.", array('%previous_name%' => $old_name, '%new_name%' => $new_name)); break; case '_pain_effect': if ($value['original_value'] != 0) { $old_name = ($old_item = self::getPainTypesOrLabel('pain_effect', $value['original_value'])) ? $old_item : TBGContext::getI18n()->__('Not determined'); } else { $old_name = TBGContext::getI18n()->__('Not determined'); } $new_name = ($new_item = self::getPainTypesOrLabel('pain_effect', $value['current_value'])) ? $new_item : TBGContext::getI18n()->__('Not determined'); $this->addLogEntry(TBGLogTable::LOG_ISSUE_PAIN_EFFECT, $old_name . ' ⇒ ' . $new_name); $comment_lines[] = TBGContext::getI18n()->__("The triaging criteria 'effect' has been updated, from '''%previous_name%''' to '''%new_name%'''.", array('%previous_name%' => $old_name, '%new_name%' => $new_name)); break; case '_pain_likelihood': if ($value['original_value'] != 0) { $old_name = ($old_item = self::getPainTypesOrLabel('pain_likelihood', $value['original_value'])) ? $old_item : TBGContext::getI18n()->__('Not determined'); } else { $old_name = TBGContext::getI18n()->__('Not determined'); } $new_name = ($new_item = self::getPainTypesOrLabel('pain_likelihood', $value['current_value'])) ? $new_item : TBGContext::getI18n()->__('Not determined'); $this->addLogEntry(TBGLogTable::LOG_ISSUE_PAIN_LIKELIHOOD, $old_name . ' ⇒ ' . $new_name); $comment_lines[] = TBGContext::getI18n()->__("The triaging criteria 'likelihood' has been updated, from '''%previous_name%''' to '''%new_name%'''.", array('%previous_name%' => $old_name, '%new_name%' => $new_name)); break; case '_user_pain': $this->addLogEntry(TBGLogTable::LOG_ISSUE_PAIN_CALCULATED, $value['original_value'] . ' ⇒ ' . $value['current_value']); $comment_lines[] = TBGContext::getI18n()->__("The calculated user pain has changed, from '''%previous_value%''' to '''%new_value%'''.", array('%previous_value%' => $value['original_value'], '%new_value%' => $value['current_value'])); break; case '_status': if ($value['original_value'] != 0) { $old_name = ($old_item = TBGContext::factory()->TBGStatus($value['original_value'])) ? $old_item->getName() : TBGContext::getI18n()->__('Unknown'); } else { $old_name = TBGContext::getI18n()->__('Not determined'); } $new_name = $this->getStatus() instanceof TBGDatatype ? $this->getStatus()->getName() : TBGContext::getI18n()->__('Not determined'); $this->addLogEntry(TBGLogTable::LOG_ISSUE_STATUS, $old_name . ' ⇒ ' . $new_name); $comment_lines[] = TBGContext::getI18n()->__("The status has been updated, from '''%previous_status%''' to '''%new_status%'''.", array('%previous_status%' => $old_name, '%new_status%' => $new_name)); break; case '_reproducability': if ($value['original_value'] != 0) { $old_name = ($old_item = TBGContext::factory()->TBGReproducability($value['original_value'])) ? $old_item->getName() : TBGContext::getI18n()->__('Unknown'); } else { $old_name = TBGContext::getI18n()->__('Not determined'); } $new_name = $this->getReproducability() instanceof TBGDatatype ? $this->getReproducability()->getName() : TBGContext::getI18n()->__('Not determined'); $this->addLogEntry(TBGLogTable::LOG_ISSUE_REPRODUCABILITY, $old_name . ' ⇒ ' . $new_name); $comment_lines[] = TBGContext::getI18n()->__("The reproducability has been updated, from '''%previous_reproducability%''' to '''%new_reproducability%'''.", array('%previous_reproducability%' => $old_name, '%new_reproducability%' => $new_name)); break; case '_priority': if ($value['original_value'] != 0) { $old_name = ($old_item = TBGContext::factory()->TBGPriority($value['original_value'])) ? $old_item->getName() : TBGContext::getI18n()->__('Unknown'); } else { $old_name = TBGContext::getI18n()->__('Not determined'); } $new_name = $this->getPriority() instanceof TBGDatatype ? $this->getPriority()->getName() : TBGContext::getI18n()->__('Not determined'); $this->addLogEntry(TBGLogTable::LOG_ISSUE_PRIORITY, $old_name . ' ⇒ ' . $new_name); $comment_lines[] = TBGContext::getI18n()->__("The priority has been updated, from '''%previous_priority%''' to '''%new_priority%'''.", array('%previous_priority%' => $old_name, '%new_priority%' => $new_name)); break; case '_assigned_to': case '_assigned_type': if (!$is_saved_assignee) { if ($value['original_value'] != 0) { $old_identifiable = null; if ($this->getChangedPropertyOriginal('_assigned_type') == TBGIdentifiableClass::TYPE_USER) { $old_identifiable = TBGContext::factory()->TBGUser($value['original_value']); } elseif ($this->getChangedPropertyOriginal('_assigned_type') == TBGIdentifiableClass::TYPE_TEAM) { $old_identifiable = TBGContext::factory()->TBGTeam($value['original_value']); } $old_name = $old_identifiable instanceof TBGIdentifiableClass ? $old_identifiable->getName() : TBGContext::getI18n()->__('Unknown'); } else { $old_name = TBGContext::getI18n()->__('Not assigned'); } $new_name = $this->getAssignee() instanceof TBGIdentifiableClass ? $this->getAssignee()->getName() : TBGContext::getI18n()->__('Not assigned'); if (!$this->isAssigned() || $this->getAssigneeType() == TBGIdentifiableClass::TYPE_TEAM) { $this->stopWorkingOnIssue(); } elseif ($this->getAssigneeType() == TBGIdentifiableClass::TYPE_USER) { $this->startWorkingOnIssue($this->getAssignee()); } $this->addLogEntry(TBGLogTable::LOG_ISSUE_ASSIGNED, $old_name . ' ⇒ ' . $new_name); $comment_lines[] = TBGContext::getI18n()->__("The assignee has been changed, from '''%previous_name%''' to '''%new_name%'''.", array('%previous_name%' => $old_name, '%new_name%' => $new_name)); $is_saved_assignee = true; } break; case '_posted_by': $old_identifiable = $value['original_value'] ? TBGContext::factory()->TBGUser($value['original_value']) : TBGContext::getI18n()->__('Unknown'); $old_name = $old_identifiable instanceof TBGIdentifiableClass ? $old_identifiable->getName() : TBGContext::getI18n()->__('Unknown'); $new_name = $this->getPostedBy()->getName(); $this->addLogEntry(TBGLogTable::LOG_ISSUE_POSTED, $old_name . ' ⇒ ' . $new_name); $comment_lines[] = TBGContext::getI18n()->__("The issue's poster has been changed, from '''%previous_name%''' to '''%new_name%'''.", array('%previous_name%' => $old_name, '%new_name%' => $new_name)); break; case '_being_worked_on_by_user': if ($value['original_value'] != 0) { $old_identifiable = TBGContext::factory()->TBGUser($value['original_value']); $old_name = $old_identifiable instanceof TBGIdentifiableClass ? $old_identifiable->getName() : TBGContext::getI18n()->__('Unknown'); } else { $old_name = TBGContext::getI18n()->__('Not being worked on'); } $new_name = $this->getUserWorkingOnIssue() instanceof TBGIdentifiableClass ? $this->getUserWorkingOnIssue()->getName() : TBGContext::getI18n()->__('Not being worked on'); $this->addLogEntry(TBGLogTable::LOG_ISSUE_USERS, $old_name . ' ⇒ ' . $new_name); $comment_lines[] = TBGContext::getI18n()->__("Information about the user working on this issue has been changed, from '''%previous_name%''' to '''%new_name%'''.", array('%previous_name%' => $old_name, '%new_name%' => $new_name)); break; case '_owner': case '_owner_type': if (!$is_saved_owner) { if ($value['original_value'] != 0) { $old_identifiable = null; if ($this->getChangedPropertyOriginal('_owner_type') == TBGIdentifiableClass::TYPE_USER) { $old_identifiable = TBGContext::factory()->TBGUser($value['original_value']); } elseif ($this->getChangedPropertyOriginal('_owner_type') == TBGIdentifiableClass::TYPE_TEAM) { $old_identifiable = TBGContext::factory()->TBGTeam($value['original_value']); } $old_name = $old_identifiable instanceof TBGIdentifiableClass ? $old_identifiable->getName() : TBGContext::getI18n()->__('Unknown'); } else { $old_name = TBGContext::getI18n()->__('Not owned by anyone'); } $new_name = $this->getOwner() instanceof TBGIdentifiableClass ? $this->getOwner()->getName() : TBGContext::getI18n()->__('Not owned by anyone'); $this->addLogEntry(TBGLogTable::LOG_ISSUE_OWNED, $old_name . ' ⇒ ' . $new_name); $comment_lines[] = TBGContext::getI18n()->__("The owner has been changed, from '''%previous_name%''' to '''%new_name%'''.", array('%previous_name%' => $old_name, '%new_name%' => $new_name)); $is_saved_owner = true; } break; case '_percent_complete': $this->addLogEntry(TBGLogTable::LOG_ISSUE_PERCENT, $value['original_value'] . '% ⇒ ' . $this->getPercentCompleted() . '%'); $comment_lines[] = TBGContext::getI18n()->__("This issue's progression has been updated to %percent_completed% percent completed.", array('%percent_completed%' => $this->getPercentCompleted())); break; case '_resolution': if ($value['original_value'] != 0) { $old_name = ($old_item = TBGContext::factory()->TBGResolution($value['original_value'])) ? $old_item->getName() : TBGContext::getI18n()->__('Unknown'); } else { $old_name = TBGContext::getI18n()->__('Not determined'); } $new_name = $this->getResolution() instanceof TBGDatatype ? $this->getResolution()->getName() : TBGContext::getI18n()->__('Not determined'); $this->addLogEntry(TBGLogTable::LOG_ISSUE_RESOLUTION, $old_name . ' ⇒ ' . $new_name); $comment_lines[] = TBGContext::getI18n()->__("The resolution has been updated, from '''%previous_resolution%''' to '''%new_resolution%'''.", array('%previous_resolution%' => $old_name, '%new_resolution%' => $new_name)); break; case '_severity': if ($value['original_value'] != 0) { $old_name = ($old_item = TBGContext::factory()->TBGSeverity($value['original_value'])) ? $old_item->getName() : TBGContext::getI18n()->__('Unknown'); } else { $old_name = TBGContext::getI18n()->__('Not determined'); } $new_name = $this->getSeverity() instanceof TBGDatatype ? $this->getSeverity()->getName() : TBGContext::getI18n()->__('Not determined'); $this->addLogEntry(TBGLogTable::LOG_ISSUE_SEVERITY, $old_name . ' ⇒ ' . $new_name); $comment_lines[] = TBGContext::getI18n()->__("The severity has been updated, from '''%previous_severity%''' to '''%new_severity%'''.", array('%previous_severity%' => $old_name, '%new_severity%' => $new_name)); break; case '_milestone': if ($value['original_value'] != 0) { $old_name = ($old_item = TBGContext::factory()->TBGMilestone($value['original_value'])) ? $old_item->getName() : TBGContext::getI18n()->__('Not determined'); } else { $old_name = TBGContext::getI18n()->__('Not determined'); } $new_name = $this->getMilestone() instanceof TBGMilestone ? $this->getMilestone()->getName() : TBGContext::getI18n()->__('Not determined'); $this->addLogEntry(TBGLogTable::LOG_ISSUE_MILESTONE, $old_name . ' ⇒ ' . $new_name); $comment_lines[] = TBGContext::getI18n()->__("The milestone has been updated, from '''%previous_milestone%''' to '''%new_milestone%'''.", array('%previous_milestone%' => $old_name, '%new_milestone%' => $new_name)); break; case '_issuetype': if ($value['original_value'] != 0) { $old_name = ($old_item = TBGContext::factory()->TBGIssuetype($value['original_value'])) ? $old_item->getName() : TBGContext::getI18n()->__('Unknown'); } else { $old_name = TBGContext::getI18n()->__('Unknown'); } $new_name = $this->getIssuetype() instanceof TBGIssuetype ? $this->getIssuetype()->getName() : TBGContext::getI18n()->__('Unknown'); $this->addLogEntry(TBGLogTable::LOG_ISSUE_ISSUETYPE, $old_name . ' ⇒ ' . $new_name); $comment_lines[] = TBGContext::getI18n()->__("The issue type has been updated, from '''%previous_type%''' to '''%new_type%'''.", array('%previous_type%' => $old_name, '%new_type%' => $new_name)); break; case '_estimated_months': case '_estimated_weeks': case '_estimated_days': case '_estimated_hours': case '_estimated_points': if (!$is_saved_estimated) { $old_time = array('months' => $this->getChangedPropertyOriginal('_estimated_months'), 'weeks' => $this->getChangedPropertyOriginal('_estimated_weeks'), 'days' => $this->getChangedPropertyOriginal('_estimated_days'), 'hours' => $this->getChangedPropertyOriginal('_estimated_hours'), 'points' => $this->getChangedPropertyOriginal('_estimated_points')); $old_formatted_time = array_sum($old_time) > 0 ? $this->getFormattedTime($old_time) : TBGContext::getI18n()->__('Not estimated'); $new_formatted_time = $this->hasEstimatedTime() ? $this->getFormattedTime($this->getEstimatedTime()) : TBGContext::getI18n()->__('Not estimated'); $this->addLogEntry(TBGLogTable::LOG_ISSUE_TIME_ESTIMATED, $old_formatted_time . ' ⇒ ' . $new_formatted_time); $comment_lines[] = TBGContext::getI18n()->__("The issue has been (re-)estimated, from '''%previous_time%''' to '''%new_time%'''.", array('%previous_time%' => $old_formatted_time, '%new_time%' => $new_formatted_time)); $is_saved_estimated = true; } break; case '_spent_months': case '_spent_weeks': case '_spent_days': case '_spent_hours': case '_spent_points': if (!$is_saved_spent) { $old_time = array('months' => $this->getChangedPropertyOriginal('_spent_months'), 'weeks' => $this->getChangedPropertyOriginal('_spent_weeks'), 'days' => $this->getChangedPropertyOriginal('_spent_days'), 'hours' => $this->getChangedPropertyOriginal('_spent_hours'), 'points' => $this->getChangedPropertyOriginal('_spent_points')); $old_formatted_time = array_sum($old_time) > 0 ? $this->getFormattedTime($old_time) : TBGContext::getI18n()->__('No time spent'); $new_formatted_time = $this->hasSpentTime() ? $this->getFormattedTime($this->getSpentTime()) : TBGContext::getI18n()->__('No time spent'); $this->addLogEntry(TBGLogTable::LOG_ISSUE_TIME_SPENT, $old_formatted_time . ' ⇒ ' . $new_formatted_time); $comment_lines[] = TBGContext::getI18n()->__("Time spent on this issue, from '''%previous_time%''' to '''%new_time%'''.", array('%previous_time%' => $old_formatted_time, '%new_time%' => $new_formatted_time)); $is_saved_spent = true; } break; case '_state': if ($this->isClosed()) { $this->addLogEntry(TBGLogTable::LOG_ISSUE_CLOSE); $comment_lines[] = TBGContext::getI18n()->__("This issue has been closed"); if ($this->getMilestone() instanceof TBGMilestone) { if ($this->getMilestone()->isSprint()) { if (!$this->getIssueType()->isTask()) { $this->setSpentPoints($this->getEstimatedPoints()); } else { if ($this->getSpentHours() < $this->getEstimatedHours()) { $this->setSpentHours($this->getEstimatedHours()); } foreach ($this->getParentIssues() as $parent_issue) { if ($parent_issue->checkTaskStates()) { $related_issues_to_save[$parent_issue->getID()] = true; } } } } $this->getMilestone()->updateStatus(); } } else { $this->addLogEntry(TBGLogTable::LOG_ISSUE_REOPEN); $comment_lines[] = TBGContext::getI18n()->__("This issue has been reopened"); } break; case '_blocking': if ($this->isBlocking()) { $this->addLogEntry(TBGLogTable::LOG_ISSUE_BLOCKED); $comment_lines[] = TBGContext::getI18n()->__("This issue is now blocking the next release"); } else { $this->addLogEntry(TBGLogTable::LOG_ISSUE_UNBLOCKED); $comment_lines[] = TBGContext::getI18n()->__("This issue is no longer blocking the next release"); } break; default: if (substr($property, 0, 12) == '_customfield') { $key = substr($property, 12); $customdatatype = TBGCustomDatatype::getByKey($key); switch ($customdatatype->getType()) { case TBGCustomDatatype::INPUT_TEXT: $new_value = $this->getCustomField($key) != '' ? $this->getCustomField($key) : TBGContext::getI18n()->__('Unknown'); $this->addLogEntry(TBGLogTable::LOG_ISSUE_CUSTOMFIELD_CHANGED, $new_value); $comment_lines[] = TBGContext::getI18n()->__("The custom field %customfield_name% has been changed to '''%new_value%'''.", array('%customfield_name%' => $customdatatype->getDescription(), '%new_value%' => $new_value)); break; case TBGCustomDatatype::INPUT_TEXTAREA_SMALL: case TBGCustomDatatype::INPUT_TEXTAREA_MAIN: $new_value = $this->getCustomField($key) != '' ? $this->getCustomField($key) : TBGContext::getI18n()->__('Unknown'); $this->addLogEntry(TBGLogTable::LOG_ISSUE_CUSTOMFIELD_CHANGED, $new_value); $comment_lines[] = TBGContext::getI18n()->__("The custom field %customfield_name% has been changed.", array('%customfield_name%' => $customdatatype->getDescription())); break; case TBGCustomDatatype::EDITIONS_CHOICE: case TBGCustomDatatype::COMPONENTS_CHOICE: case TBGCustomDatatype::RELEASES_CHOICE: case TBGCustomDatatype::STATUS_CHOICE: $old_object = null; $new_object = null; try { switch ($customdatatype->getType()) { case TBGCustomDatatype::EDITIONS_CHOICE: $old_object = TBGContext::factory()->TBGEdition($value['original_value']); break; case TBGCustomDatatype::COMPONENTS_CHOICE: $old_object = TBGContext::factory()->TBGComponent($value['original_value']); break; case TBGCustomDatatype::RELEASES_CHOICE: $old_object = TBGContext::factory()->TBGBuild($value['original_value']); case TBGCustomDatatype::STATUS_CHOICE: $old_object = TBGContext::factory()->TBGStatus($value['original_value']); break; } } catch (Exception $e) { } try { switch ($customdatatype->getType()) { case TBGCustomDatatype::EDITIONS_CHOICE: $new_object = TBGContext::factory()->TBGEdition($this->getCustomField($key)); break; case TBGCustomDatatype::COMPONENTS_CHOICE: $new_object = TBGContext::factory()->TBGComponent($this->getCustomField($key)); break; case TBGCustomDatatype::RELEASES_CHOICE: $new_object = TBGContext::factory()->TBGBuild($this->getCustomField($key)); case TBGCustomDatatype::STATUS_CHOICE: $new_object = TBGContext::factory()->TBGStatus($this->getCustomField($key)); break; } } catch (Exception $e) { } $old_value = is_object($old_object) ? $old_object->getName() : TBGContext::getI18n()->__('Unknown'); $new_value = is_object($new_object) ? $new_object->getName() : TBGContext::getI18n()->__('Unknown'); $this->addLogEntry(TBGLogTable::LOG_ISSUE_CUSTOMFIELD_CHANGED, $old_value . ' ⇒ ' . $new_value); $comment_lines[] = TBGContext::getI18n()->__("The custom field %customfield_name% has been updated, from '''%previous_value%''' to '''%new_value%'''.", array('%customfield_name%' => $customdatatype->getDescription(), '%previous_value%' => $old_value, '%new_value%' => $new_value)); break; default: $old_value = ($old_item = TBGCustomDatatypeOption::getByValueAndKey($value['original_value'], $key)) ? $old_item->getName() : TBGContext::getI18n()->__('Unknown'); $new_value = $this->getCustomField($key) instanceof TBGCustomDatatypeOption ? $this->getCustomField($key)->getName() : TBGContext::getI18n()->__('Unknown'); $this->addLogEntry(TBGLogTable::LOG_ISSUE_CUSTOMFIELD_CHANGED, $old_value . ' ⇒ ' . $new_value); $comment_lines[] = TBGContext::getI18n()->__("The custom field %customfield_name% has been updated, from '''%previous_value%''' to '''%new_value%'''.", array('%customfield_name%' => $customdatatype->getDescription(), '%previous_value%' => $old_value, '%new_value%' => $new_value)); break; } } break; } } } if (count($comment_lines) == 0) { $comment = TBGContext::getI18n()->__("The issue has been updated"); $this->comment = $this->addSystemComment(TBGContext::getI18n()->__('Issue updated'), $comment, TBGContext::getUser()->getID()); $this->comment_lines = $comment_lines; } else { $comment = TBGContext::getI18n()->__("The issue was updated with the following change(s):%list_of_changes%", array('%list_of_changes%' => "\n* " . join("\n* ", $comment_lines)), true); $this->comment = $this->addSystemComment(TBGContext::getI18n()->__('Issue updated'), $comment, TBGContext::getUser()->getID()); $this->comment_lines = $comment_lines; } if ($is_saved_estimated) { B2DB::getTable('TBGIssueEstimates')->saveEstimate($this->getID(), $this->_estimated_months, $this->_estimated_weeks, $this->_estimated_days, $this->_estimated_hours, $this->_estimated_points); } if ($is_saved_spent) { B2DB::getTable('TBGIssueSpentTimes')->saveSpentTime($this->getID(), $this->_spent_months, $this->_spent_weeks, $this->_spent_days, $this->_spent_hours, $this->_spent_points); } $this->related_issues_to_save = $related_issues_to_save; $this->_clearChangedProperties(); }
public function findIssues($filters = array(), $results_per_page = 30, $offset = 0, $groupby = null, $grouporder = null) { $crit = $this->getCriteria(); $crit->addWhere(self::DELETED, false); if (count($filters) > 0) { $crit->addJoin(TBGIssueCustomFieldsTable::getTable(), TBGIssueCustomFieldsTable::ISSUE_ID, TBGIssuesTable::ID); foreach ($filters as $filter => $filter_info) { if (array_key_exists('value', $filter_info) && in_array($filter_info['operator'], array('=', '!=', '<=', '>=', '<', '>'))) { if ($filter == 'text') { if ($filter_info['value'] != '') { $searchterm = strpos($filter_info['value'], '%') !== false ? $filter_info['value'] : "%{$filter_info['value']}%"; if ($filter_info['operator'] == '=') { $ctn = $crit->returnCriterion(self::TITLE, $searchterm, B2DBCriteria::DB_LIKE); $ctn->addOr(self::DESCRIPTION, $searchterm, B2DBCriteria::DB_LIKE); $ctn->addOr(self::REPRODUCTION_STEPS, $searchterm, B2DBCriteria::DB_LIKE); $ctn->addOr(TBGIssueCustomFieldsTable::OPTION_VALUE, $searchterm, B2DBCriteria::DB_LIKE); } else { $ctn = $crit->returnCriterion(self::TITLE, $searchterm, B2DBCriteria::DB_NOT_LIKE); $ctn->addWhere(self::DESCRIPTION, $searchterm, B2DBCriteria::DB_NOT_LIKE); $ctn->addWhere(self::REPRODUCTION_STEPS, $searchterm, B2DBCriteria::DB_NOT_LIKE); $ctn->addOr(TBGIssueCustomFieldsTable::OPTION_VALUE, $searchterm, B2DBCriteria::DB_NOT_LIKE); } $crit->addWhere($ctn); } } elseif (in_array($filter, self::getValidSearchFilters())) { $crit->addWhere($this->getB2DBName() . '.' . $filter, $filter_info['value'], $filter_info['operator']); } elseif (TBGCustomDatatype::doesKeyExist($filter)) { $customdatatype = TBGCustomDatatype::getByKey($filter); $ctn = $crit->returnCriterion(TBGIssueCustomFieldsTable::CUSTOMFIELDS_ID, $customdatatype->getID()); $ctn->addWhere(TBGIssueCustomFieldsTable::OPTION_VALUE, $filter_info['value'], $filter_info['operator']); $crit->addWhere($ctn); } } else { if (in_array($filter, self::getValidSearchFilters())) { $first_val = array_shift($filter_info); if ($filter == 'text') { $filter_info = $first_val; if ($filter_info['value'] != '') { $searchterm = strpos($filter_info['value'], '%') !== false ? $filter_info['value'] : "%{$filter_info['value']}%"; if ($filter_info['operator'] == '=') { $ctn = $crit->returnCriterion(self::TITLE, $searchterm, B2DBCriteria::DB_LIKE); $ctn->addOr(self::DESCRIPTION, $searchterm, B2DBCriteria::DB_LIKE); $ctn->addOr(self::REPRODUCTION_STEPS, $searchterm, B2DBCriteria::DB_LIKE); } else { $ctn = $crit->returnCriterion(self::TITLE, $searchterm, B2DBCriteria::DB_NOT_LIKE); $ctn->addWhere(self::DESCRIPTION, $searchterm, B2DBCriteria::DB_NOT_LIKE); $ctn->addWhere(self::REPRODUCTION_STEPS, $searchterm, B2DBCriteria::DB_NOT_LIKE); } $crit->addWhere($ctn); } } else { $ctn = $crit->returnCriterion($this->getB2DBName() . '.' . $filter, $first_val['value'], $first_val['operator']); if (count($filter_info) > 0) { foreach ($filter_info as $single_filter) { if (in_array($single_filter['operator'], array('=', '<=', '>=', '<', '>'))) { $ctn->addOr($this->getB2DBName() . '.' . $filter, $single_filter['value'], $single_filter['operator']); } elseif ($single_filter['operator'] == '!=') { $ctn->addWhere($this->getB2DBName() . '.' . $filter, $single_filter['value'], $single_filter['operator']); } } } $crit->addWhere($ctn); } } elseif (TBGCustomDatatype::doesKeyExist($filter)) { $customdatatype = TBGCustomDatatype::getByKey($filter); $first_val = array_shift($filter_info); $ctn = $crit->returnCriterion(TBGIssueCustomFieldsTable::CUSTOMFIELDS_ID, $customdatatype->getID()); $ctn->addWhere(TBGIssueCustomFieldsTable::OPTION_VALUE, $first_val['value'], $first_val['operator']); if (count($filter_info) > 0) { foreach ($filter_info as $single_filter) { if (in_array($single_filter['operator'], array('=', '!=', '<=', '>=', '<', '>'))) { $ctn->addOr(TBGIssueCustomFieldsTable::OPTION_VALUE, $single_filter['value'], $single_filter['operator']); } } } $crit->addWhere($ctn); } } } } $crit->addSelectionColumn(self::ID); $crit->setDistinct(); if ($offset != 0) { $crit->setOffset($offset); } $crit2 = clone $crit; $count = $this->doCount($crit2); if ($count > 0) { if ($results_per_page != 0) { $crit->setLimit($results_per_page); } if ($offset != 0) { $crit->setOffset($offset); } if ($groupby !== null) { $grouporder = $grouporder !== null ? $grouporder == 'asc' ? B2DBCriteria::SORT_ASC : B2DBCriteria::SORT_DESC : B2DBCriteria::SORT_ASC; switch ($groupby) { case 'category': $crit->addSelectionColumn(TBGListTypesTable::NAME); $crit->addOrderBy(TBGListTypesTable::NAME, $grouporder); break; case 'status': $crit->addSelectionColumn(self::STATUS); $crit->addOrderBy(self::STATUS, $grouporder); break; case 'milestone': $crit->addSelectionColumn(self::MILESTONE); $crit->addSelectionColumn(self::PERCENT_COMPLETE); $crit->addOrderBy(self::MILESTONE, $grouporder); $crit->addOrderBy(self::PERCENT_COMPLETE, 'desc'); break; case 'assignee': $crit->addSelectionColumn(self::ASSIGNED_TYPE); $crit->addSelectionColumn(self::ASSIGNED_TO); $crit->addOrderBy(self::ASSIGNED_TYPE); $crit->addOrderBy(self::ASSIGNED_TO, $grouporder); break; case 'state': $crit->addSelectionColumn(self::STATE); $crit->addOrderBy(self::STATE, $grouporder); break; case 'severity': $crit->addSelectionColumn(self::SEVERITY); $crit->addOrderBy(self::SEVERITY, $grouporder); break; case 'user_pain': $crit->addSelectionColumn(self::USER_PAIN); $crit->addOrderBy(self::USER_PAIN, $grouporder); break; case 'votes': $crit->addSelectionColumn(self::VOTES_TOTAL); $crit->addOrderBy(self::VOTES_TOTAL, $grouporder); break; case 'resolution': $crit->addSelectionColumn(self::RESOLUTION); $crit->addOrderBy(self::RESOLUTION, $grouporder); break; case 'priority': $crit->addSelectionColumn(self::PRIORITY); $crit->addOrderBy(self::PRIORITY, $grouporder); break; case 'issuetype': $crit->addJoin(TBGIssueTypesTable::getTable(), TBGIssueTypesTable::ID, self::ISSUE_TYPE); $crit->addSelectionColumn(TBGIssueTypesTable::NAME); $crit->addOrderBy(TBGIssueTypesTable::NAME, $grouporder); break; case 'edition': $crit->addJoin(TBGIssueAffectsEditionTable::getTable(), TBGIssueAffectsEditionTable::ISSUE, self::ID); $crit->addJoin(TBGEditionsTable::getTable(), TBGEditionsTable::ID, TBGIssueAffectsEditionTable::EDITION, array(), B2DBCriteria::DB_LEFT_JOIN, TBGIssueAffectsEditionTable::getTable()); $crit->addSelectionColumn(TBGEditionsTable::NAME); $crit->addOrderBy(TBGEditionsTable::NAME, $grouporder); break; case 'build': $crit->addJoin(TBGIssueAffectsBuildTable::getTable(), TBGIssueAffectsBuildTable::ISSUE, self::ID); $crit->addJoin(TBGBuildsTable::getTable(), TBGBuildsTable::ID, TBGIssueAffectsBuildTable::BUILD, array(), B2DBCriteria::DB_LEFT_JOIN, TBGIssueAffectsBuildTable::getTable()); $crit->addSelectionColumn(TBGBuildsTable::NAME); $crit->addOrderBy(TBGBuildsTable::NAME, $grouporder); break; case 'component': $crit->addJoin(TBGIssueAffectsComponentTable::getTable(), TBGIssueAffectsComponentTable::ISSUE, self::ID); $crit->addJoin(TBGComponentsTable::getTable(), TBGComponentsTable::ID, TBGIssueAffectsComponentTable::COMPONENT, array(), B2DBCriteria::DB_LEFT_JOIN, TBGIssueAffectsComponentTable::getTable()); $crit->addSelectionColumn(TBGComponentsTable::NAME); $crit->addOrderBy(TBGComponentsTable::NAME, $grouporder); break; } } $crit->addSelectionColumn(self::LAST_UPDATED); $crit->addOrderBy(self::LAST_UPDATED, 'asc'); $res = $this->doSelect($crit, 'none'); $ids = array(); while ($row = $res->getNextRow()) { $ids[] = $row->get(self::ID); } $ids = array_reverse($ids); $crit2 = $this->getCriteria(); $crit2->addWhere(self::ID, $ids, B2DBCriteria::DB_IN); $crit2->addOrderBy(self::ID, $ids); $res = $this->doSelect($crit2); return array($res, $count); } else { return array(null, 0); } }