protected function _upgradeFrom4dot1dot5(framework\Request $request) { set_time_limit(0); \thebuggenie\core\entities\tables\Issues::getTable()->upgrade(\thebuggenie\core\modules\installation\upgrade_415\Issue::getB2DBTable()); \thebuggenie\core\entities\tables\IssueSpentTimes::getTable()->upgrade(\thebuggenie\core\modules\installation\upgrade_415\IssueSpentTime::getB2DBTable()); \thebuggenie\core\entities\tables\IssueEstimates::getTable()->upgrade(\thebuggenie\core\modules\installation\upgrade_415\IssueEstimatesTable::getTable()); $this->upgrade_complete = true; $this->current_version = '4.1.6'; }
protected function _populateBurndownData() { if ($this->_burndowndata === null) { $this->_burndowndata = array(); $issues = array(); foreach ($this->getIssues() as $issue) { $issues[] = (int) $issue->getID(); foreach ($issue->getChildIssues() as $child_issue) { $issues[] = (int) $child_issue->getID(); } } $estimations = tables\IssueEstimates::getTable()->getEstimatesByDateAndIssueIDs($this->getStartingDate(), $this->getScheduledDate(), $issues); $spent_times = tables\IssueSpentTimes::getTable()->getSpentTimesByDateAndIssueIDs($this->getStartingDate(), $this->getScheduledDate(), $issues); $burndown = array(); foreach ($spent_times['hours'] as $key => $val) { $spent_times['hours'][$key] = round($spent_times['hours'][$key] / 100, 2); } foreach ($estimations['hours'] as $key => $val) { $burndown['hours'][$key] = array_key_exists($key, $spent_times['hours']) ? $val - $spent_times['hours'][$key] : $val; } foreach ($estimations['points'] as $key => $val) { $burndown['points'][$key] = array_key_exists($key, $spent_times['points']) ? $val - $spent_times['points'][$key] : $val; } $this->_burndowndata = array('estimations' => $estimations, 'spent_times' => $spent_times, 'burndown' => $burndown); } }
protected function moveIssues($project_id, $to_scope_id) { $crit = Issues::getTable()->getCriteria(); $crit->addWhere('issues.project_id', $project_id); $crit->addSelectionColumn('issues.id', 'id'); $issue_ids = []; if ($res = Issues::getTable()->doSelect($crit)) { while ($row = $res->getNextRow()) { $issue_ids[] = $row['id']; } } $this->cliEcho("------------------\n"); $this->cliEcho('Moving '); $this->cliEcho(count($issue_ids), 'white', 'bold'); $this->cliEcho(" issues\n"); $this->cliEcho("------------------\n"); if (!$issue_ids) { return; } $this->cliEcho("Moving comments... "); $comments_crit = Comments::getTable()->getCriteria(); $comments_crit->addUpdate('comments.scope', $to_scope_id); $comments_crit->addWhere('comments.target_id', $issue_ids, Criteria::DB_IN); $comments_crit->addWhere('comments.target_type', Comment::TYPE_ISSUE); Comments::getTable()->doUpdate($comments_crit); $this->cliEcho(" done\n"); $this->cliEcho("Moving log items... "); $logs_crit = Log::getTable()->getCriteria(); $logs_crit->addUpdate('log.scope', $to_scope_id); $logs_crit->addWhere('log.target', $issue_ids, Criteria::DB_IN); $logs_crit->addWhere('log.target_type', Log::TYPE_ISSUE); Log::getTable()->doUpdate($logs_crit); $this->cliEcho(" done\n"); $this->cliEcho("Moving attachments... "); $file_ids_crit = IssueFiles::getTable()->getCriteria(); $file_ids_crit->addWhere('issuefiles.issue_id', $issue_ids, Criteria::DB_IN); $file_ids_crit->addSelectionColumn('issuefiles.file_id', 'file_id'); $file_ids_crit->addSelectionColumn('issuefiles.id', 'id'); $file_ids = []; $issue_file_ids = []; if ($res = IssueFiles::getTable()->doSelect($file_ids_crit)) { while ($row = $res->getNextRow()) { $file_ids[] = $row['file_id']; $issue_file_ids[] = $row['id']; } } if (count($file_ids)) { $file_crit = Files::getTable()->getCriteria(); $file_crit->addUpdate('files.scope', $to_scope_id); $file_crit->addWhere('files.id', $file_ids, Criteria::DB_IN); Files::getTable()->doUpdate($file_crit); $issue_file_crit = IssueFiles::getTable()->getCriteria(); $issue_file_crit->addUpdate('issuefiles.scope', $to_scope_id); $issue_file_crit->addWhere('issuefiles.id', $issue_file_ids, Criteria::DB_IN); IssueFiles::getTable()->doUpdate($issue_file_crit); } $this->cliEcho(" done\n"); $this->cliEcho("Moving calculations and estimations... "); $estimates_crit = IssueEstimates::getTable()->getCriteria(); $estimates_crit->addUpdate('issue_estimates.scope', $to_scope_id); $estimates_crit->addWhere('issue_estimates.issue_id', $issue_ids, Criteria::DB_IN); IssueEstimates::getTable()->doUpdate($estimates_crit); $spent_crit = IssueSpentTimes::getTable()->getCriteria(); $spent_crit->addUpdate('issue_spenttimes.scope', $to_scope_id); $spent_crit->addWhere('issue_spenttimes.issue_id', $issue_ids, Criteria::DB_IN); IssueSpentTimes::getTable()->doUpdate($spent_crit); $this->cliEcho(" done\n"); $this->cliEcho("Moving links, related and affected items"); $tables = ['\\thebuggenie\\core\\entities\\tables\\IssueAffectsBuild' => 'issueaffectsbuild', '\\thebuggenie\\core\\entities\\tables\\IssueAffectsComponent' => 'issueaffectscomponent', '\\thebuggenie\\core\\entities\\tables\\IssueAffectsEdition' => 'issueaffectsedition']; foreach ($tables as $class_name => $table_name) { $crit = $class_name::getTable()->getCriteria(); $crit->addUpdate($table_name . '.scope', $to_scope_id); $crit->addWhere($table_name . '.issue', $issue_ids, Criteria::DB_IN); $class_name::getTable()->doUpdate($crit); } $links_crit = Links::getTable()->getCriteria(); $links_crit->addUpdate('links.scope', $to_scope_id); $links_crit->addWhere('links.target_id', $issue_ids, Criteria::DB_IN); $links_crit->addWhere('links.target_type', 'issue'); Links::getTable()->doUpdate($links_crit); $related_crit = IssueRelations::getTable()->getCriteria(); $related_crit->addUpdate('issuerelations.scope', $to_scope_id); $ctn = $related_crit->returnCriterion('issuerelations.child_id', $issue_ids, Criteria::DB_IN); $ctn->addOr('issuerelations.parent_id', $issue_ids, Criteria::DB_IN); $related_crit->addWhere($ctn); $votes_crit = Votes::getTable()->getCriteria(); $votes_crit->addUpdate('votes.scope', $to_scope_id); $votes_crit->addWhere('votes.target', $issue_ids, Criteria::DB_IN); Votes::getTable()->doUpdate($votes_crit); $this->cliEcho(" done\n"); $this->cliEcho("Updating user issue bookmarks"); $user_issues_crit = UserIssues::getTable()->getCriteria(); $user_issues_crit->addUpdate('userissues.scope', $to_scope_id); $user_issues_crit->addWhere('userissues.issue', $issue_ids, Criteria::DB_IN); UserIssues::getTable()->doUpdate($user_issues_crit); $this->cliEcho(" done\n"); $this->updateCustomFields($issue_ids, $to_scope_id); $crit = Issues::getTable()->getCriteria(); $crit->addUpdate('issues.scope', $to_scope_id); $crit->addWhere('issues.id', $issue_ids, Criteria::DB_IN); Issues::getTable()->doUpdate($crit); $this->cliEcho("------------------\n"); $this->cliEcho("Done moving issues\n"); $this->cliEcho("------------------\n"); }
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(tables\Log::LOG_ISSUE_UPDATE_TITLE, framework\Context::getI18n()->__("Title updated"), $original_value, $compare_value); break; case '_shortname': $this->addLogEntry(tables\Log::LOG_ISSUE_UPDATE_SHORTNAME, framework\Context::getI18n()->__("Issue label updated"), $original_value, $compare_value); break; case '_description': $this->addLogEntry(tables\Log::LOG_ISSUE_UPDATE_DESCRIPTION, framework\Context::getI18n()->__("Description updated"), $original_value, $compare_value); break; case '_reproduction_steps': $this->addLogEntry(tables\Log::LOG_ISSUE_UPDATE_REPRODUCTIONSTEPS, framework\Context::getI18n()->__("Reproduction steps updated"), $original_value, $compare_value); break; case '_category': if ($original_value != 0) { $old_name = ($old_item = \thebuggenie\core\entities\Category::getB2DBTable()->selectById($original_value)) ? $old_item->getName() : framework\Context::getI18n()->__('Not determined'); } else { $old_name = framework\Context::getI18n()->__('Not determined'); } $new_name = $this->getCategory() instanceof Datatype ? $this->getCategory()->getName() : framework\Context::getI18n()->__('Not determined'); $this->addLogEntry(tables\Log::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 : framework\Context::getI18n()->__('Not determined'); } else { $old_name = framework\Context::getI18n()->__('Not determined'); } $new_name = ($new_item = self::getPainTypesOrLabel('pain_bug_type', $value['current_value'])) ? $new_item : framework\Context::getI18n()->__('Not determined'); $this->addLogEntry(tables\Log::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 : framework\Context::getI18n()->__('Not determined'); } else { $old_name = framework\Context::getI18n()->__('Not determined'); } $new_name = ($new_item = self::getPainTypesOrLabel('pain_effect', $value['current_value'])) ? $new_item : framework\Context::getI18n()->__('Not determined'); $this->addLogEntry(tables\Log::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 : framework\Context::getI18n()->__('Not determined'); } else { $old_name = framework\Context::getI18n()->__('Not determined'); } $new_name = ($new_item = self::getPainTypesOrLabel('pain_likelihood', $value['current_value'])) ? $new_item : framework\Context::getI18n()->__('Not determined'); $this->addLogEntry(tables\Log::LOG_ISSUE_PAIN_LIKELIHOOD, $old_name . ' ⇒ ' . $new_name, $original_value, $compare_value); break; case '_user_pain': $this->addLogEntry(tables\Log::LOG_ISSUE_PAIN_CALCULATED, $original_value . ' ⇒ ' . $value['current_value']); break; case '_status': if ($original_value != 0) { $old_name = ($old_item = \thebuggenie\core\entities\Status::getB2DBTable()->selectById($original_value)) ? $old_item->getName() : framework\Context::getI18n()->__('Unknown'); } else { $old_name = framework\Context::getI18n()->__('Not determined'); } $new_name = $this->getStatus() instanceof Datatype ? $this->getStatus()->getName() : framework\Context::getI18n()->__('Not determined'); $this->addLogEntry(tables\Log::LOG_ISSUE_STATUS, $old_name . ' ⇒ ' . $new_name, $original_value, $compare_value); break; case '_reproducability': if ($original_value != 0) { $old_name = ($old_item = \thebuggenie\core\entities\Reproducability::getB2DBTable()->selectById($original_value)) ? $old_item->getName() : framework\Context::getI18n()->__('Unknown'); } else { $old_name = framework\Context::getI18n()->__('Not determined'); } $new_name = $this->getReproducability() instanceof Datatype ? $this->getReproducability()->getName() : framework\Context::getI18n()->__('Not determined'); $this->addLogEntry(tables\Log::LOG_ISSUE_REPRODUCABILITY, $old_name . ' ⇒ ' . $new_name, $original_value, $compare_value); break; case '_priority': if ($original_value != 0) { $old_name = ($old_item = \thebuggenie\core\entities\Priority::getB2DBTable()->selectById($original_value)) ? $old_item->getName() : framework\Context::getI18n()->__('Unknown'); } else { $old_name = framework\Context::getI18n()->__('Not determined'); } $new_name = $this->getPriority() instanceof Datatype ? $this->getPriority()->getName() : framework\Context::getI18n()->__('Not determined'); $this->addLogEntry(tables\Log::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 \thebuggenie\core\entities\common\Identifiable ? $this->getAssignee()->getName() : framework\Context::getI18n()->__('Not assigned'); if ($this->getAssignee() instanceof \thebuggenie\core\entities\User) { $this->startWorkingOnIssue($this->getAssignee()); } $this->addLogEntry(tables\Log::LOG_ISSUE_ASSIGNED, $new_name); $is_saved_assignee = true; } break; case '_posted_by': $old_identifiable = $original_value ? \thebuggenie\core\entities\User::getB2DBTable()->selectById($original_value) : framework\Context::getI18n()->__('Unknown'); $old_name = $old_identifiable instanceof \thebuggenie\core\entities\User ? $old_identifiable->getName() : framework\Context::getI18n()->__('Unknown'); $new_name = $this->getPostedBy()->getName(); $this->addLogEntry(tables\Log::LOG_ISSUE_POSTED, $old_name . ' ⇒ ' . $new_name, $original_value, $compare_value); break; case '_being_worked_on_by_user': if ($original_value != 0) { $old_identifiable = \thebuggenie\core\entities\User::getB2DBTable()->selectById($original_value); $old_name = $old_identifiable instanceof \thebuggenie\core\entities\User ? $old_identifiable->getName() : framework\Context::getI18n()->__('Unknown'); } else { $old_name = framework\Context::getI18n()->__('Not being worked on'); } $new_name = $this->getUserWorkingOnIssue() instanceof \thebuggenie\core\entities\User ? $this->getUserWorkingOnIssue()->getName() : framework\Context::getI18n()->__('Not being worked on'); $this->addLogEntry(tables\Log::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 \thebuggenie\core\entities\common\Identifiable ? $this->getOwner()->getName() : framework\Context::getI18n()->__('Not owned by anyone'); $this->addLogEntry(tables\Log::LOG_ISSUE_OWNED, $new_name); $is_saved_owner = true; } break; case '_percent_complete': $this->addLogEntry(tables\Log::LOG_ISSUE_PERCENT, $original_value . '% ⇒ ' . $this->getPercentCompleted() . '', $original_value, $compare_value); break; case '_resolution': if ($original_value != 0) { $old_name = ($old_item = \thebuggenie\core\entities\Resolution::getB2DBTable()->selectById($original_value)) ? $old_item->getName() : framework\Context::getI18n()->__('Unknown'); } else { $old_name = framework\Context::getI18n()->__('Not determined'); } $new_name = $this->getResolution() instanceof Datatype ? $this->getResolution()->getName() : framework\Context::getI18n()->__('Not determined'); $this->addLogEntry(tables\Log::LOG_ISSUE_RESOLUTION, $old_name . ' ⇒ ' . $new_name, $original_value, $compare_value); break; case '_severity': if ($original_value != 0) { $old_name = ($old_item = \thebuggenie\core\entities\Severity::getB2DBTable()->selectById($original_value)) ? $old_item->getName() : framework\Context::getI18n()->__('Unknown'); } else { $old_name = framework\Context::getI18n()->__('Not determined'); } $new_name = $this->getSeverity() instanceof Datatype ? $this->getSeverity()->getName() : framework\Context::getI18n()->__('Not determined'); $this->addLogEntry(tables\Log::LOG_ISSUE_SEVERITY, $old_name . ' ⇒ ' . $new_name, $original_value, $compare_value); break; case '_milestone': if ($original_value != 0) { $old_name = ($old_item = \thebuggenie\core\entities\Milestone::getB2DBTable()->selectById($original_value)) ? $old_item->getName() : framework\Context::getI18n()->__('Not determined'); } else { $old_name = framework\Context::getI18n()->__('Not determined'); } $new_name = $this->getMilestone() instanceof \thebuggenie\core\entities\Milestone ? $this->getMilestone()->getName() : framework\Context::getI18n()->__('Not determined'); $this->addLogEntry(tables\Log::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 = Issuetype::getB2DBTable()->selectById($original_value)) ? $old_item->getName() : framework\Context::getI18n()->__('Unknown'); } else { $old_name = framework\Context::getI18n()->__('Unknown'); } $new_name = $this->getIssuetype() instanceof \thebuggenie\core\entities\Issuetype ? $this->getIssuetype()->getName() : framework\Context::getI18n()->__('Unknown'); $this->addLogEntry(tables\Log::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 ? Issue::getFormattedTime($old_time) : framework\Context::getI18n()->__('Not estimated'); $new_formatted_time = $this->hasEstimatedTime() ? Issue::getFormattedTime($this->getEstimatedTime()) : framework\Context::getI18n()->__('Not estimated'); $this->addLogEntry(tables\Log::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' => round($this->getChangedPropertyOriginal('_spent_hours') / 100, 2), 'points' => $this->getChangedPropertyOriginal('_spent_points')); $old_formatted_time = array_sum($old_time) > 0 ? Issue::getFormattedTime($old_time) : framework\Context::getI18n()->__('No time spent'); $new_formatted_time = $this->hasSpentTime() ? Issue::getFormattedTime($this->getSpentTime()) : framework\Context::getI18n()->__('No time spent'); $this->addLogEntry(tables\Log::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(tables\Log::LOG_ISSUE_CLOSE); if ($this->getMilestone() instanceof \thebuggenie\core\entities\Milestone) { 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(); $this->getMilestone()->save(); } } else { $this->addLogEntry(tables\Log::LOG_ISSUE_REOPEN); } break; case '_blocking': if ($this->isBlocking()) { $this->addLogEntry(tables\Log::LOG_ISSUE_BLOCKED); } else { $this->addLogEntry(tables\Log::LOG_ISSUE_UNBLOCKED); } break; default: if (mb_substr($property, 0, 12) == '_customfield') { $key = mb_substr($property, 12); $customdatatype = CustomDatatype::getByKey($key); switch ($customdatatype->getType()) { case CustomDatatype::INPUT_TEXT: $new_value = $this->getCustomField($key) != '' ? $this->getCustomField($key) : framework\Context::getI18n()->__('Unknown'); $this->addLogEntry(tables\Log::LOG_ISSUE_CUSTOMFIELD_CHANGED, $key . ': ' . $new_value, $original_value, $compare_value); break; case CustomDatatype::INPUT_TEXTAREA_SMALL: case CustomDatatype::INPUT_TEXTAREA_MAIN: $new_value = $this->getCustomField($key) != '' ? $this->getCustomField($key) : framework\Context::getI18n()->__('Unknown'); $this->addLogEntry(tables\Log::LOG_ISSUE_CUSTOMFIELD_CHANGED, $key . ': ' . $new_value, $original_value, $compare_value); break; case CustomDatatype::EDITIONS_CHOICE: case CustomDatatype::COMPONENTS_CHOICE: case CustomDatatype::RELEASES_CHOICE: case CustomDatatype::MILESTONE_CHOICE: case CustomDatatype::STATUS_CHOICE: case CustomDatatype::TEAM_CHOICE: case CustomDatatype::USER_CHOICE: case CustomDatatype::CLIENT_CHOICE: $old_object = null; $new_object = null; try { switch ($customdatatype->getType()) { case CustomDatatype::EDITIONS_CHOICE: $old_object = Edition::getB2DBTable()->selectById($original_value); break; case CustomDatatype::COMPONENTS_CHOICE: $old_object = Component::getB2DBTable()->selectById($original_value); break; case CustomDatatype::RELEASES_CHOICE: $old_object = Build::getB2DBTable()->selectById($original_value); break; case CustomDatatype::MILESTONE_CHOICE: $old_object = Milestone::getB2DBTable()->selectById($original_value); break; case CustomDatatype::STATUS_CHOICE: $old_object = Status::getB2DBTable()->selectById($original_value); break; case CustomDatatype::TEAM_CHOICE: $old_object = Team::getB2DBTable()->selectById($original_value); break; case CustomDatatype::USER_CHOICE: $old_object = User::getB2DBTable()->selectById($original_value); break; case CustomDatatype::CLIENT_CHOICE: $old_object = Client::getB2DBTable()->selectById($original_value); break; } } catch (\Exception $e) { } try { switch ($customdatatype->getType()) { case CustomDatatype::EDITIONS_CHOICE: case CustomDatatype::COMPONENTS_CHOICE: case CustomDatatype::RELEASES_CHOICE: case CustomDatatype::MILESTONE_CHOICE: case CustomDatatype::STATUS_CHOICE: case CustomDatatype::TEAM_CHOICE: case CustomDatatype::USER_CHOICE: case CustomDatatype::CLIENT_CHOICE: $new_object = $this->getCustomField($key); break; } } catch (\Exception $e) { } $old_value = is_object($old_object) ? $old_object->getName() : framework\Context::getI18n()->__('Unknown'); $new_value = is_object($new_object) ? $new_object->getName() : framework\Context::getI18n()->__('Unknown'); $this->addLogEntry(tables\Log::LOG_ISSUE_CUSTOMFIELD_CHANGED, $key . ': ' . $old_value . ' ⇒ ' . $new_value, $original_value, $compare_value); break; default: $old_item = null; try { $old_item = $original_value ? new CustomDatatypeOption($original_value) : null; } catch (\Exception $e) { } $old_value = $old_item instanceof \thebuggenie\core\entities\CustomDatatypeOption ? $old_item->getName() : framework\Context::getI18n()->__('Unknown'); $new_value = $this->getCustomField($key) instanceof \thebuggenie\core\entities\CustomDatatypeOption ? $this->getCustomField($key)->getName() : framework\Context::getI18n()->__('Unknown'); $this->addLogEntry(tables\Log::LOG_ISSUE_CUSTOMFIELD_CHANGED, $key . ': ' . $old_value . ' ⇒ ' . $new_value, $original_value, $compare_value); break; } } break; } } } if ($is_saved_estimated) { tables\IssueEstimates::getTable()->saveEstimate($this->getID(), $this->_estimated_months, $this->_estimated_weeks, $this->_estimated_days, $this->_estimated_hours, $this->_estimated_points); } } return $related_issues_to_save; }
protected function _populateBurndownData() { if ($this->_burndowndata === null) { $this->_burndowndata = array(); $issues = array(); foreach ($this->getIssues() as $issue) { $issues[] = (int) $issue->getID(); foreach ($issue->getChildIssues() as $child_issue) { $issues[] = (int) $child_issue->getID(); } } $estimations = tables\IssueEstimates::getTable()->getEstimatesByDateAndIssueIDs($this->getStartingDate(), $this->getScheduledDate(), $issues); $spent_times = tables\IssueSpentTimes::getTable()->getSpentTimesByDateAndIssueIDs($this->getStartingDate(), $this->getScheduledDate(), $issues); $burndown = array(); foreach ($spent_times['hours'] as $key => $val) { $spent_times['hours'][$key] = round($spent_times['hours'][$key] / 100, 2); } $total_estimations_hours = array_sum($estimations['hours']); if (array_sum($spent_times['hours']) > $total_estimations_hours) { $total_estimations_hours = array_sum($spent_times['hours']); } $prev_key = null; foreach ($estimations['hours'] as $key => $val) { if (!is_null($prev_key) && array_key_exists($prev_key, $spent_times['hours'])) { $total_estimations_hours -= $spent_times['hours'][$prev_key]; } else { if (isset($spent_times['hours_spent_before'])) { $spent_times['hours_spent_before'] = round($spent_times['hours_spent_before'] / 100, 2); $total_estimations_hours -= $spent_times['hours_spent_before']; } } $burndown['hours'][$key] = $total_estimations_hours; $prev_key = $key; } $total_estimations_points = array_sum($estimations['points']); if (array_sum($spent_times['points']) > $total_estimations_points) { $total_estimations_points = array_sum($spent_times['points']); } $prev_key = null; foreach ($estimations['points'] as $key => $val) { if (!is_null($prev_key) && array_key_exists($prev_key, $spent_times['points'])) { $total_estimations_points -= $spent_times['points'][$prev_key]; } else { if (isset($spent_times['points_spent_before'])) { $total_estimations_points -= $spent_times['points_spent_before']; } } $burndown['points'][$key] = $total_estimations_points; $prev_key = $key; } $this->_burndowndata = array('estimations' => $estimations, 'spent_times' => $spent_times, 'burndown' => $burndown); } }