public function runIssueEditTimeSpent(framework\Request $request) { try { $entry_id = $request['entry_id']; $spenttime = $entry_id ? tables\IssueSpentTimes::getTable()->selectById($entry_id) : new entities\IssueSpentTime(); if ($issue_id = $request['issue_id']) { $issue = entities\Issue::getB2DBTable()->selectById($issue_id); } else { throw new \Exception('no issue'); } framework\Context::loadLibrary('common'); $spenttime->editOrAdd($issue, $this->getUser(), array_only_with_default($request->getParameters(), array_merge(array('timespent_manual', 'timespent_specified_type', 'timespent_specified_value', 'timespent_activitytype', 'timespent_comment', 'edited_at'), \thebuggenie\core\entities\common\Timeable::getUnitsWithPoints()))); } catch (\Exception $e) { $this->getResponse()->setHttpStatus(400); return $this->renderJSON(array('edited' => 'error', 'error' => $e->getMessage())); } $this->return_data = array('edited' => 'ok'); }
/** * Assign an issue to an epic * * @Route(url="/assign/issue/epic/:epic_id") * * @param framework\Request $request */ public function runAssignEpic(framework\Request $request) { try { $epic = \thebuggenie\core\entities\Issue::getB2DBTable()->selectById((int) $request['epic_id']); $issue = \thebuggenie\core\entities\Issue::getB2DBTable()->selectById((int) $request['issue_id']); $epic->addChildIssue($issue, true); return $this->renderJSON(array('issue_id' => $issue->getID(), 'epic_id' => $epic->getID(), 'closed_pct' => $epic->getEstimatedPercentCompleted(), 'num_child_issues' => $epic->countChildIssues(), 'estimate' => \thebuggenie\core\entities\Issue::getFormattedTime($epic->getEstimatedTime()), 'text_color' => $epic->getAgileTextColor())); } catch (\Exception $e) { $this->getResponse()->setHttpStatus(400); return $this->renderJSON(array('error' => framework\Context::getI18n()->__('An error occured when trying to assign the issue to the epic'))); } }
/** * Returns the object which the notification is for * * @return \thebuggenie\core\entities\common\IdentifiableScoped */ public function getTarget() { if ($this->_target === null) { if ($this->_module_name == 'core') { switch ($this->_notification_type) { case self::TYPE_ARTICLE_COMMENTED: case self::TYPE_ISSUE_COMMENTED: case self::TYPE_COMMENT_MENTIONED: $this->_target = tables\Comments::getTable()->selectById((int) $this->_target_id); break; case self::TYPE_ISSUE_UPDATED: case self::TYPE_ISSUE_CREATED: case self::TYPE_ISSUE_MENTIONED: $this->_target = \thebuggenie\core\entities\Issue::getB2DBTable()->selectById((int) $this->_target_id); break; case self::TYPE_ARTICLE_CREATED: case self::TYPE_ARTICLE_UPDATED: case self::TYPE_ARTICLE_MENTIONED: $this->_target = Articles::getTable()->selectById((int) $this->_target_id); break; } } else { $event = new \thebuggenie\core\framework\Event('core', 'thebuggenie\\core\\entities\\Notification::getTarget', $this); $event->triggerUntilProcessed(); $this->_target = $event->getReturnValue(); } } return $this->_target; }
public function runTransitionIssues(framework\Request $request) { try { try { $transition = entities\WorkflowTransition::getB2DBTable()->selectById($request['transition_id']); } catch (\Exception $e) { $this->getResponse()->setHttpStatus(400); return $this->renderJSON(array('error' => $this->getI18n()->__('This is not a valid transition'))); } $issue_ids = $request['issue_ids']; $status = null; $closed = false; foreach ($issue_ids as $issue_id) { $issue = entities\Issue::getB2DBTable()->selectById((int) $issue_id); if (!$issue->isWorkflowTransitionsAvailable() || !$transition->validateFromRequest($request)) { $this->getResponse()->setHttpStatus(400); return $this->renderJSON(array('error' => framework\Context::getI18n()->__('The transition could not be applied to issue %issue_number because of %errors', array('%issue_number' => $issue->getFormattedIssueNo(), '%errors' => join(', ', $transition->getValidationErrors()))))); } try { $transition->transitionIssueToOutgoingStepFromRequest($issue, $request); } catch (\Exception $e) { $this->getResponse()->setHttpStatus(400); framework\Logging::log(framework\Logging::LEVEL_WARNING, 'Transition ' . $transition->getID() . ' failed for issue ' . $issue_id); framework\Logging::log(framework\Logging::LEVEL_WARNING, $e->getMessage()); return $this->renderJSON(array('error' => $this->getI18n()->__('The transition failed because of an error in the workflow. Check your workflow configuration.'))); } if ($status === null) { $status = $issue->getStatus(); } $closed = $issue->isClosed(); } framework\Context::loadLibrary('common'); $options = array('issue_ids' => array_keys($issue_ids), 'last_updated' => tbg_formatTime(time(), 20), 'closed' => $closed); $options['status'] = array('color' => $status->getColor(), 'name' => $status->getName(), 'id' => $status->getID()); if ($request->hasParameter('milestone_id')) { $milestone = new entities\Milestone($request['milestone_id']); $options['milestone_id'] = $milestone->getID(); $options['milestone_name'] = $milestone->getName(); } foreach (array('resolution', 'priority', 'category', 'severity') as $item) { $class = "\\thebuggenie\\core\\entities\\" . ucfirst($item); if ($request->hasParameter($item . '_id')) { if ($item_id = $request[$item . '_id']) { $itemobject = new $class($item_id); $itemname = $itemobject->getName(); } else { $item_id = 0; $itemname = '-'; } $options[$item] = array('name' => $itemname, 'id' => $item_id); } else { $method = 'get' . ucfirst($item); $itemname = $issue->{$method}() instanceof $class ? $issue->{$method}()->getName() : '-'; $item_id = $issue->{$method}() instanceof $class ? $issue->{$method}()->getID() : 0; $options[$item] = array('name' => $itemname, 'id' => $item_id); } } return $this->renderJSON($options); } catch (\Exception $e) { $this->getResponse()->setHttpStatus(400); framework\Logging::log(framework\Logging::LEVEL_WARNING, $e->getMessage()); return $this->renderJSON(array('error' => $this->getI18n()->__('An error occured when trying to apply the transition'))); } }
public function isValid($input) { switch ($this->_name) { case self::RULE_MAX_ASSIGNED_ISSUES: $num_issues = (int) $this->getRuleValue(); return $num_issues ? (bool) (count(framework\Context::getUser()->getUserAssignedIssues()) < $num_issues) : true; break; case self::RULE_TEAM_MEMBERSHIP_VALID: $valid_items = explode(',', $this->getRuleValue()); $teams = \thebuggenie\core\entities\Team::getAll(); if ($this->isPost()) { if ($input instanceof \thebuggenie\core\entities\Issue) { $assignee = $input->getAssignee(); } } if (!isset($assignee)) { $assignee = framework\Context::getUser(); } if ($assignee instanceof \thebuggenie\core\entities\User) { if (count($valid_items) == 1 && reset($valid_items) == '') { return true; } foreach ($valid_items as $team_id) { if ($assignee->isMemberOfTeam($teams[$team_id])) { return true; } } } elseif ($assignee instanceof \thebuggenie\core\entities\Team) { foreach ($valid_items as $team_id) { if ($assignee->getID() == $team_id) { return true; } } } return false; case self::RULE_ISSUE_IN_MILESTONE_VALID: $valid_items = explode(',', $this->getRuleValue()); if ($input instanceof \thebuggenie\core\entities\Issue) { $issue = $input; } else { if ($input->hasParameter('issue_id')) { $issue = \thebuggenie\core\entities\Issue::getB2DBTable()->selectByID((int) $input->getParameter('issue_id')); } } if (isset($issue) && $issue instanceof \thebuggenie\core\entities\Issue) { if (!$issue->getMilestone() instanceof \thebuggenie\core\entities\Milestone) { return false; } if (count($valid_items) == 1 && reset($valid_items) == '') { return true; } return in_array($issue->getMilestone()->getID(), $valid_items); } return false; case self::RULE_STATUS_VALID: case self::RULE_PRIORITY_VALID: case self::RULE_RESOLUTION_VALID: case self::RULE_REPRODUCABILITY_VALID: $valid_items = explode(',', $this->getRuleValue()); $valid = false; if ($this->_name == self::RULE_STATUS_VALID) { $fieldname = 'Status'; $fieldname_small = 'status'; } elseif ($this->_name == self::RULE_RESOLUTION_VALID) { $fieldname = 'Resolution'; $fieldname_small = 'resolution'; } elseif ($this->_name == self::RULE_REPRODUCABILITY_VALID) { $fieldname = 'Reproducability'; $fieldname_small = 'reproducability'; } elseif ($this->_name == self::RULE_PRIORITY_VALID) { $fieldname = 'Priority'; $fieldname_small = 'priority'; } else { throw new framework\exceptions\ConfigurationException(framework\Context::getI18n()->__('Invalid workflow validation rule: %rule_name', array('%rule_name' => $this->_name))); } if (!$this->getRuleValue()) { if ($input instanceof \thebuggenie\core\entities\Issue) { $getter = "get{$fieldname}"; if (is_object($input->{$getter}())) { $valid = true; } } elseif ($input instanceof framework\Request) { if ($input->getParameter("{$fieldname_small}_id") && Status::has($input->getParameter("{$fieldname_small}_id"))) { $valid = true; } } } else { foreach ($valid_items as $item) { if ($input instanceof \thebuggenie\core\entities\Issue) { $type = "\\thebuggenie\\core\\entities\\{$fieldname}"; $getter = "get{$fieldname}"; if (is_object($input->{$getter}()) && $type::getB2DBTable()->selectByID((int) $item)->getID() == $input->{$getter}()->getID()) { $valid = true; break; } } elseif ($input instanceof framework\Request) { if ($input->getParameter("{$fieldname_small}_id") == $item) { $valid = true; break; } } } } return $valid; break; default: if ($this->isCustom()) { switch ($this->getCustomType()) { case CustomDatatype::RADIO_CHOICE: case CustomDatatype::DROPDOWN_CHOICE_TEXT: case CustomDatatype::TEAM_CHOICE: case CustomDatatype::STATUS_CHOICE: case CustomDatatype::MILESTONE_CHOICE: case CustomDatatype::CLIENT_CHOICE: case CustomDatatype::COMPONENTS_CHOICE: case CustomDatatype::EDITIONS_CHOICE: case CustomDatatype::RELEASES_CHOICE: $valid_items = explode(',', $this->getRuleValue()); if ($input instanceof \thebuggenie\core\entities\Issue) { $value = $input->getCustomField($this->getCustomFieldname()); } elseif ($input instanceof framework\Request) { $value = $input->getParameter($this->getCustomFieldname() . "_id"); } $valid = false; if (!$this->getRuleValue()) { foreach ($this->getCustomField()->getOptions() as $item) { if ($item->getID() == $value) { $valid = true; break; } } } else { foreach ($valid_items as $item) { if ($value instanceof Identifiable && $value->getID() == $item) { $valid = true; break; } elseif (is_numeric($value) && $value == $item) { $valid = true; break; } } } return $valid; break; } } else { $event = new \thebuggenie\core\framework\Event('core', 'WorkflowTransitionValidationRule::isValid', $this); $event->setReturnValue(false); $event->triggerUntilProcessed(array('input' => $input)); return $event->getReturnValue(); } } }
/** * Returns an array of teams which the current user is a member of * * @return array|Team */ public function getTeams() { $this->_populateTeams(); $teams = $this->_teams['assigned']; if (framework\Context::isProjectContext()) { $project = framework\Context::getCurrentProject(); } else { if (framework\Context::getRequest()->hasParameter('issue_id')) { $issue = Issue::getB2DBTable()->selectById(framework\Context::getRequest()->getParameter('issue_id')); if ($issue instanceof Issue && $issue->getProject() instanceof Project) { $project = $issue->getProject(); } } } if (isset($project)) { $project_assigned_teams = $project->getAssignedTeams(); foreach ($teams as $team_id => $team) { if (!array_key_exists($team_id, $project_assigned_teams)) { unset($teams[$team_id]); } } } return $teams; }
public function componentCommentitem() { if ($this->comment->getTargetType() == 1) { try { $this->issue = entities\Issue::getB2DBTable()->selectById($this->comment->getTargetID()); } catch (\Exception $e) { } } }
protected function _postSave($is_new) { $this->_saveCustomFieldValues(); if (!$is_new) { $related_issues_to_save = $this->_processChanges(); $comment = isset($this->_save_comment) ? $this->_save_comment : $this->addSystemComment('', framework\Context::getUser()->getID()); $this->triggerSaveEvent($comment, framework\Context::getUser()); if (count($related_issues_to_save)) { foreach (array_keys($related_issues_to_save) as $i_id) { $related_issue = \thebuggenie\core\entities\Issue::getB2DBTable()->selectById((int) $i_id); $related_issue->save(); } } } else { $_description_parser = $this->_getDescriptionParser(); $_reproduction_steps_parser = $this->_getReproductionStepsParser(); if (!is_null($_description_parser) && $_description_parser->hasMentions()) { foreach ($_description_parser->getMentions() as $user) { if ($user->getID() == framework\Context::getUser()->getID()) { continue; } $this->_addNotification(Notification::TYPE_ISSUE_MENTIONED, $user, $this->getPostedBy()); } } if (!is_null($_reproduction_steps_parser) && $_reproduction_steps_parser->hasMentions()) { foreach ($_reproduction_steps_parser->getMentions() as $user) { if ($user->getID() == framework\Context::getUser()->getID()) { continue; } $this->_addNotification(Notification::TYPE_ISSUE_MENTIONED, $user, $this->getPostedBy()); } } $this->addLogEntry(tables\Log::LOG_ISSUE_CREATED, null, false, $this->getPosted()); $this->_addCreateNotifications($this->getPostedBy()); \thebuggenie\core\framework\Event::createNew('core', 'thebuggenie\\core\\entities\\Issue::createNew', $this)->trigger(); } if (in_array(\thebuggenie\core\framework\Settings::getUserSetting(\thebuggenie\core\framework\Settings::SETTINGS_USER_SUBSCRIBE_CREATED_UPDATED_COMMENTED_ISSUES, framework\Context::getUser()->getID()), array(null, true))) { $this->addSubscriber(framework\Context::getUser()->getID()); } $this->_clearChangedProperties(); $this->_log_items_added = array(); $this->getProject()->clearRecentActivities(); if ($this->isChildIssue() && ($this->hasEstimatedTime() || $this->hasSpentTime())) { foreach ($this->getParentIssues() as $issue) { $issue->calculateTime(); $issue->save(); } } if ($this->getMilestone() instanceof \thebuggenie\core\entities\Milestone) { $this->getMilestone()->updateStatus(); $this->getMilestone()->save(); } return true; }
public function getTarget() { if ($this->_target === null) { switch ($this->getTargetType()) { case self::TYPE_ISSUE: $this->_target = \thebuggenie\core\entities\Issue::getB2DBTable()->selectById($this->_target_id); break; case self::TYPE_ARTICLE: $this->_target = publish\entities\tables\Articles::getTable()->selectById($this->_target_id); break; default: $event = \thebuggenie\core\framework\Event::createNew('core', 'Comment::getTarget', $this); $event->trigger(); $this->_target = $event->getReturnValue(); } } return $this->_target; }
public function runAddAffected(framework\Request $request) { framework\Context::loadLibrary('ui'); try { $issue = entities\Issue::getB2DBTable()->selectById($request['issue_id']); $statuses = entities\Status::getAll(); switch ($request['item_type']) { case 'edition': if (!$issue->getProject()->isEditionsEnabled()) { $this->getResponse()->setHttpStatus(400); return $this->renderJSON(array('error' => framework\Context::getI18n()->__('Editions are disabled'))); } elseif (!$issue->canEditAffectedEditions()) { $this->getResponse()->setHttpStatus(400); return $this->renderJSON(array('error' => framework\Context::getI18n()->__('You are not allowed to do this'))); } $edition = entities\Edition::getB2DBTable()->selectById($request['which_item_edition']); if (tables\IssueAffectsEdition::getTable()->getByIssueIDandEditionID($issue->getID(), $edition->getID())) { $this->getResponse()->setHttpStatus(400); return $this->renderJSON(array('error' => framework\Context::getI18n()->__('%item is already affected by this issue', array('%item' => $edition->getName())))); } $result = $issue->addAffectedEdition($edition); if ($result !== false) { $itemtype = 'edition'; $item = $result; $itemtypename = framework\Context::getI18n()->__('Edition'); $content = get_component_html('main/affecteditem', array('item' => $item, 'itemtype' => $itemtype, 'itemtypename' => $itemtypename, 'issue' => $issue, 'statuses' => $statuses)); } $message = framework\Context::getI18n()->__('Edition <b>%edition</b> is now affected by this issue', array('%edition' => $edition->getName()), true); break; case 'component': if (!$issue->getProject()->isComponentsEnabled()) { $this->getResponse()->setHttpStatus(400); return $this->renderJSON(array('error' => framework\Context::getI18n()->__('Components are disabled'))); } elseif (!$issue->canEditAffectedComponents()) { $this->getResponse()->setHttpStatus(400); return $this->renderJSON(array('error' => framework\Context::getI18n()->__('You are not allowed to do this'))); } $component = entities\Component::getB2DBTable()->selectById($request['which_item_component']); if (tables\IssueAffectsComponent::getTable()->getByIssueIDandComponentID($issue->getID(), $component->getID())) { $this->getResponse()->setHttpStatus(400); return $this->renderJSON(array('error' => framework\Context::getI18n()->__('%item is already affected by this issue', array('%item' => $component->getName())))); } $result = $issue->addAffectedComponent($component); if ($result !== false) { $itemtype = 'component'; $item = $result; $itemtypename = framework\Context::getI18n()->__('Component'); $content = get_component_html('main/affecteditem', array('item' => $item, 'itemtype' => $itemtype, 'itemtypename' => $itemtypename, 'issue' => $issue, 'statuses' => $statuses)); } $message = framework\Context::getI18n()->__('Component <b>%component</b> is now affected by this issue', array('%component' => $component->getName()), true); break; case 'build': if (!$issue->getProject()->isBuildsEnabled()) { $this->getResponse()->setHttpStatus(400); return $this->renderJSON(array('error' => framework\Context::getI18n()->__('Releases are disabled'))); } elseif (!$issue->canEditAffectedBuilds()) { $this->getResponse()->setHttpStatus(400); return $this->renderJSON(array('error' => framework\Context::getI18n()->__('You are not allowed to do this'))); } $build = entities\Build::getB2DBTable()->selectById($request['which_item_build']); if (tables\IssueAffectsBuild::getTable()->getByIssueIDandBuildID($issue->getID(), $build->getID())) { $this->getResponse()->setHttpStatus(400); return $this->renderJSON(array('error' => framework\Context::getI18n()->__('%item is already affected by this issue', array('%item' => $build->getName())))); } $result = $issue->addAffectedBuild($build); if ($result !== false) { $itemtype = 'build'; $item = $result; $itemtypename = framework\Context::getI18n()->__('Release'); $content = get_component_html('main/affecteditem', array('item' => $item, 'itemtype' => $itemtype, 'itemtypename' => $itemtypename, 'issue' => $issue, 'statuses' => $statuses)); } $message = framework\Context::getI18n()->__('Release <b>%build</b> is now affected by this issue', array('%build' => $build->getName()), true); break; default: throw new \Exception('Internal error'); } $editions = array(); $components = array(); $builds = array(); if ($issue->getProject()->isEditionsEnabled()) { $editions = $issue->getEditions(); } if ($issue->getProject()->isComponentsEnabled()) { $components = $issue->getComponents(); } if ($issue->getProject()->isBuildsEnabled()) { $builds = $issue->getBuilds(); } $count = count($editions) + count($components) + count($builds); return $this->renderJSON(array('content' => $content, 'message' => $message, 'itemcount' => $count)); } catch (\Exception $e) { $this->getResponse()->setHttpStatus(400); return $this->renderJSON(array('error' => $e->getMessage())); } }
<?php } ?> <title><?php echo \thebuggenie\core\framework\Settings::getSiteHeaderName() . ' ~ ' . __('%project_name project timeline', array('%project_name' => \thebuggenie\core\framework\Context::getCurrentProject()->getName())); ?> </title> <link><?php echo make_url('project_timeline', array('project_key' => \thebuggenie\core\framework\Context::getCurrentProject()->getKey()), false); ?> </link> </image> <?php foreach ($recent_activities as $timestamp => $activities) { foreach ($activities as $activity) { if (array_key_exists('target_type', $activity) && $activity['target_type'] == 1 && ($issue = \thebuggenie\core\entities\Issue::getB2DBTable()->selectById($activity['target'])) && $issue instanceof \thebuggenie\core\entities\Issue) { if ($issue->isDeleted()) { continue; } ?> <item> <title><![CDATA[ <?php $activity['text'] = str_replace("⇒", '->', html_entity_decode($activity['text'])); switch ($activity['change_type']) { case \thebuggenie\core\entities\tables\Log::LOG_ISSUE_CREATED: echo __('Issue created'); break; case \thebuggenie\core\entities\tables\Log::LOG_ISSUE_CLOSE: echo __('Issue closed %text', array('%text' => $activity['text'])); break;