/** * Return all commits for a given issue * @param TBGIssue $issue * @return array */ public static function getCommitsByIssue(TBGIssue $issue) { $data = array(); if (!is_object(TBGVCSIntegrationIssueLinksTable::getTable()->getByIssueID($issue->getID()))) { return array(); } foreach (TBGVCSIntegrationIssueLinksTable::getTable()->getByIssueID($issue->getID())->getAllRows() as $row) { $data[] = TBGContext::factory()->TBGVCSIntegrationIssueLink($row->get(TBGVCSIntegrationIssueLinksTable::ID), $row); } return $data; }
protected function _getIssueRelatedUsers(TBGIssue $issue) { $uids = array(); $cu = TBGContext::getUser()->getID(); $ns = $this->getSetting(self::NOTIFY_ISSUE_UPDATED_SELF, $cu); // Add all users who's marked this issue as interesting $uids = TBGUserIssuesTable::getTable()->getUserIDsByIssueID($issue->getID()); // Add all users from the team owning the issue if valid // or add the owning user if a user owns the issue if ($issue->getOwnerType() == TBGIdentifiableClass::TYPE_TEAM) { foreach ($issue->getOwner()->getMembers() as $member) { if ($member->getID() == $cu && !$ns) { continue; } $uids[$member->getID()] = $member->getID(); } } elseif ($issue->getOwnerType() == TBGIdentifiableClass::TYPE_USER) { if (!($issue->getOwnerID() == $cu && !$ns)) { $uids[$issue->getOwnerID()] = $issue->getOwnerID(); } } // Add the poster if ($this->getSetting(self::NOTIFY_ISSUE_POSTED_UPDATED, $issue->getPostedByID())) { if (!($issue->getPostedByID() == $cu && !$ns)) { $uids[$issue->getPostedByID()] = $issue->getPostedByID(); } } // Add all users from the team assigned to the issue if valid // or add the assigned user if a user is assigned to the issue if ($issue->getAssigneeType() == TBGIdentifiableClass::TYPE_TEAM) { // Get team member IDs foreach ($issue->getAssignee()->getMembers() as $member) { if ($member->getID() == $cu && !$ns) { continue; } if (!$this->getSetting(self::NOTIFY_ISSUE_TEAMASSIGNED_UPDATED, $member->getID())) { continue; } $uids[$member->getID()] = $member->getID(); } } elseif ($issue->getAssigneeType() == TBGIdentifiableClass::TYPE_USER) { if (!($issue->getAssigneeID() == $cu && !$ns) && !!$this->getSetting(self::NOTIFY_ISSUE_ASSIGNED_UPDATED, $issue->getAssigneeID())) { $uids[$issue->getAssigneeID()] = $issue->getAssigneeID(); } } // Add all users in the team who leads the project, if valid // or add the user who leads the project, if valid if ($issue->getProject()->getLeaderType() == TBGIdentifiableClass::TYPE_TEAM) { foreach ($issue->getProject()->getLeader()->getMembers() as $member) { if ($member->getID() == $cu && !$ns) { continue; } if (!$this->getSetting(self::NOTIFY_ISSUE_RELATED_PROJECT_TEAMASSIGNED, $member->getID())) { continue; } $uids[$member->getID()] = $member->getID(); } } elseif ($issue->getProject()->getLeaderType() == TBGIdentifiableClass::TYPE_USER) { if (!($issue->getProject()->getLeaderID() == $cu && !$ns) && !!$this->getSetting(self::NOTIFY_ISSUE_PROJECT_ASSIGNED, $issue->getProject()->getLeaderID())) { $uids[$issue->getProject()->getLeaderID()] = $issue->getProject()->getLeaderID(); } } // Same for QA if ($issue->getProject()->getQaResponsibleType() == TBGIdentifiableClass::TYPE_TEAM) { foreach ($issue->getProject()->getQaResponsible()->getMembers() as $member) { if ($member->getID() == $cu && !$ns) { continue; } if (!$this->getSetting(self::NOTIFY_ISSUE_RELATED_PROJECT_TEAMASSIGNED, $member->getID())) { continue; } $uids[$member->getID()] = $member->getID(); } } elseif ($issue->getProject()->getQaResponsibleType() == TBGIdentifiableClass::TYPE_USER) { if (!($issue->getProject()->getQaResponsibleID() == $cu && !$ns) && !!$this->getSetting(self::NOTIFY_ISSUE_PROJECT_ASSIGNED, $issue->getProject()->getQaResponsibleID())) { $uids[$issue->getProject()->getQaResponsibleID()] = $issue->getProject()->getQaResponsibleID(); } } foreach ($issue->getProject()->getAssignedTeams() as $team_id => $assignments) { foreach (TBGContext::factory()->TBGTeam($team_id)->getMembers() as $member) { if ($member->getID() == $cu && !$ns) { continue; } if (!$this->getSetting(self::NOTIFY_ISSUE_RELATED_PROJECT_TEAMASSIGNED, $member->getID())) { continue; } $uids[$member->getID()] = $member->getID(); } } foreach ($issue->getProject()->getAssignedUsers() as $user_id => $assignments) { $member = TBGContext::factory()->TBGUser($user_id); if (!($member->getID() == $cu && !$ns) && !!$this->getSetting(self::NOTIFY_ISSUE_PROJECT_ASSIGNED, $member->getID())) { $uids[$member->getID()] = $member->getID(); } } // Add all users relevant for all affected editions foreach ($issue->getEditions() as $edition_list) { if ($edition_list['edition']->getLeaderType() == TBGIdentifiableClass::TYPE_TEAM) { foreach ($edition_list['edition']->getLeader()->getMembers() as $member) { if ($member->getID() == $cu && !$ns) { continue; } if (!$this->getSetting(self::NOTIFY_ISSUE_RELATED_PROJECT_TEAMASSIGNED, $member->getID())) { continue; } $uids[$member->getID()] = $member->getID(); } } elseif ($edition_list['edition']->getLeaderType() == TBGIdentifiableClass::TYPE_USER) { if (!($edition_list['edition']->getLeaderID() == $cu && !$ns) && !!$this->getSetting(self::NOTIFY_ISSUE_PROJECT_ASSIGNED, $edition_list['edition']->getLeaderID())) { $uids[$edition_list['edition']->getLeaderID()] = $edition_list['edition']->getLeaderID(); } } if ($edition_list['edition']->getQaResponsibleType() == TBGIdentifiableClass::TYPE_TEAM) { foreach ($edition_list['edition']->getQaResponsible()->getMembers() as $member) { if ($member->getID() == $cu && !$ns) { continue; } if (!$this->getSetting(self::NOTIFY_ISSUE_RELATED_PROJECT_TEAMASSIGNED, $member->getID())) { continue; } $uids[$member->getID()] = $member->getID(); } } elseif ($edition_list['edition']->getQaResponsibleType() == TBGIdentifiableClass::TYPE_USER) { if (!($edition_list['edition']->getQaResponsibleID() == $cu && !$ns) && !!$this->getSetting(self::NOTIFY_ISSUE_PROJECT_ASSIGNED, $edition_list['edition']->getQaResponsibleID())) { $uids[$edition_list['edition']->getQaResponsibleID()] = $edition_list['edition']->getQaResponsibleID(); } } foreach ($edition_list['edition']->getAssignedTeams() as $team_id => $assignments) { foreach (TBGContext::factory()->TBGTeam($team_id)->getMembers() as $member) { if ($member->getID() == $cu && !$ns) { continue; } if (!$this->getSetting(self::NOTIFY_ISSUE_RELATED_PROJECT_TEAMASSIGNED, $member->getID())) { continue; } $uids[$member->getID()] = $member->getID(); } } foreach ($edition_list['edition']->getAssignedUsers() as $user_id => $assignments) { $member = TBGContext::factory()->TBGUser($user_id); if ($member->getID() == $cu && !$ns) { continue; } if (!$this->getSetting(self::NOTIFY_ISSUE_PROJECT_ASSIGNED, $member->getID())) { continue; } $uids[$member->getID()] = $member->getID(); } } // Add all users relevant for all affected components foreach ($issue->getComponents() as $component_list) { foreach ($component_list['component']->getAssignedTeams() as $team_id => $assignments) { foreach (TBGContext::factory()->TBGTeam($team_id)->getMembers() as $member) { if ($member->getID() == $cu && !$ns) { continue; } if (!$this->getSetting(self::NOTIFY_ISSUE_RELATED_PROJECT_TEAMASSIGNED, $member->getID())) { continue; } $uids[$member->getID()] = $member->getID(); } } foreach ($component_list['component']->getAssignedUsers() as $user_id => $assignments) { $member = TBGContext::factory()->TBGUser($user_id); if ($member->getID() == $cu && !$ns) { continue; } if (!$this->getSetting(self::NOTIFY_ISSUE_PROJECT_ASSIGNED, $member->getID())) { continue; } $uids[$member->getID()] = $member->getID(); } } foreach ($uids as $uid => $val) { if ($this->getSetting(self::NOTIFY_ISSUE_ONCE, $uid)) { if ($this->getSetting(self::NOTIFY_ISSUE_ONCE . '_' . $issue->getID(), $uid)) { unset($uids[$uid]); continue; } else { $this->saveSetting(self::NOTIFY_ISSUE_ONCE . '_' . $issue->getID(), 1, $uid); } } $uids[$uid] = TBGContext::factory()->TBGUser($uid); } return $uids; }
public function runDoImportCSV(TBGRequest $request) { try { if ($request->getParameter('csv_data') == '') { throw new Exception(TBGContext::getI18n()->__('No data supplied to import')); } // Split data into individual lines $data = str_replace("\r\n", "\n", $request->getParameter('csv_data')); $data = explode("\n", $data); if (count($data) <= 1) { throw new Exception(TBGContext::getI18n()->__('Insufficient data to import')); } $headerrow = $data[0]; $headerrow = html_entity_decode($headerrow, ENT_QUOTES); $headerrow = explode(',', $headerrow); $headerrow2 = array(); for ($i = 0; $i != count($headerrow); $i++) { $headerrow2[$i] = trim($headerrow[$i], '" '); } $errors = array(); // inspect for correct rows switch ($request->getParameter('type')) { case 'clients': $namecol = null; $emailcol = null; $telephonecol = null; $faxcol = null; $websitecol = null; for ($i = 0; $i != count($headerrow2); $i++) { if ($headerrow2[$i] == 'name') { $namecol = $i; } elseif ($headerrow2[$i] == 'email') { $emailcol = $i; } elseif ($headerrow2[$i] == 'telephone') { $telephonecol = $i; } elseif ($headerrow2[$i] == 'fax') { $faxcol = $i; } elseif ($headerrow2[$i] == 'website') { $websitecol = $i; } } $rowlength = count($headerrow2); if ($namecol === null) { $errors[] = TBGContext::getI18n()->__('Required column \'%col%\' not found in header row', array('%col%' => 'name')); } break; case 'projects': $namecol = null; $prefix = null; $scrum = null; $owner = null; $owner_type = null; $lead = null; $lead_type = null; $qa = null; $qa_type = null; $descr = null; $doc_url = null; $freelance = null; $en_builds = null; $en_comps = null; $en_editions = null; $workflow_id = null; $client = null; $show_summary = null; $summary_type = null; $issuetype_scheme = null; $allow_reporting = null; $autoassign = null; for ($i = 0; $i != count($headerrow2); $i++) { if ($headerrow2[$i] == 'name') { $namecol = $i; } elseif ($headerrow2[$i] == 'prefix') { $prefix = $i; } elseif ($headerrow2[$i] == 'scrum') { $scrum = $i; } elseif ($headerrow2[$i] == 'owner') { $owner = $i; } elseif ($headerrow2[$i] == 'owner_type') { $owner_type = $i; } elseif ($headerrow2[$i] == 'lead') { $lead = $i; } elseif ($headerrow2[$i] == 'lead_type') { $lead_type = $i; } elseif ($headerrow2[$i] == 'qa') { $qa = $i; } elseif ($headerrow2[$i] == 'qa_type') { $qa_type = $i; } elseif ($headerrow2[$i] == 'descr') { $descr = $i; } elseif ($headerrow2[$i] == 'doc_url') { $doc_url = $i; } elseif ($headerrow2[$i] == 'freelance') { $freelance = $i; } elseif ($headerrow2[$i] == 'en_builds') { $en_builds = $i; } elseif ($headerrow2[$i] == 'en_comps') { $en_comps = $i; } elseif ($headerrow2[$i] == 'en_editions') { $en_editions = $i; } elseif ($headerrow2[$i] == 'workflow_id') { $workflow_id = $i; } elseif ($headerrow2[$i] == 'client') { $client = $i; } elseif ($headerrow2[$i] == 'show_summary') { $show_summary = $i; } elseif ($headerrow2[$i] == 'summary_type') { $summary_type = $i; } elseif ($headerrow2[$i] == 'issuetype_scheme') { $issuetype_scheme = $i; } elseif ($headerrow2[$i] == 'allow_reporting') { $allow_reporting = $i; } elseif ($headerrow2[$i] == 'autoassign') { $autoassign = $i; } } $rowlength = count($headerrow2); if ($namecol === null) { $errors[] = TBGContext::getI18n()->__('Required column \'%col%\' not found in header row', array('%col%' => 'name')); } break; case 'issues': $title = null; $project = null; $descr = null; $repro = null; $state = null; $status = null; $posted_by = null; $owner = null; $owner_type = null; $assigned = null; $assigned_type = null; $resolution = null; $issue_type = null; $priority = null; $category = null; $severity = null; $reproducability = null; $votes = null; $percentage = null; $blocking = null; $milestone = null; for ($i = 0; $i != count($headerrow2); $i++) { if ($headerrow2[$i] == 'title') { $title = $i; } elseif ($headerrow2[$i] == 'project') { $project = $i; } elseif ($headerrow2[$i] == 'assigned') { $assigned = $i; } elseif ($headerrow2[$i] == 'repro') { $repro = $i; } elseif ($headerrow2[$i] == 'state') { $state = $i; } elseif ($headerrow2[$i] == 'status') { $status = $i; } elseif ($headerrow2[$i] == 'posted_by') { $posted_by = $i; } elseif ($headerrow2[$i] == 'owner') { $owner = $i; } elseif ($headerrow2[$i] == 'owner_type') { $owner_type = $i; } elseif ($headerrow2[$i] == 'assigned') { $assigned = $i; } elseif ($headerrow2[$i] == 'assigned_type') { $assigned_type = $i; } elseif ($headerrow2[$i] == 'resolution') { $resolution = $i; } elseif ($headerrow2[$i] == 'issue_type') { $issue_type = $i; } elseif ($headerrow2[$i] == 'priority') { $priority = $i; } elseif ($headerrow2[$i] == 'category') { $category = $i; } elseif ($headerrow2[$i] == 'severity') { $severity = $i; } elseif ($headerrow2[$i] == 'reproducability') { $reproducability = $i; } elseif ($headerrow2[$i] == 'votes') { $votes = $i; } elseif ($headerrow2[$i] == 'percentage') { $percentage = $i; } elseif ($headerrow2[$i] == 'blocking') { $blocking = $i; } elseif ($headerrow2[$i] == 'type') { $issue_type = $i; } elseif ($headerrow2[$i] == 'milestone') { $milestone = $i; } } $rowlength = count($headerrow2); if ($title === null) { $errors[] = TBGContext::getI18n()->__('Required column \'%col%\' not found in header row', array('%col%' => 'title')); } if ($project === null) { $errors[] = TBGContext::getI18n()->__('Required column \'%col%\' not found in header row', array('%col%' => 'project')); } if ($issue_type === null) { $errors[] = TBGContext::getI18n()->__('Required column \'%col%\' not found in header row', array('%col%' => 'issue_type')); } break; default: throw new Exception('Sorry, this type is unimplemented'); break; } // Check if rows are long enough for ($i = 1; $i != count($data); $i++) { $activerow = $data[$i]; $activerow = html_entity_decode($activerow, ENT_QUOTES); $activerow = explode(',', $activerow); if (count($activerow) != $rowlength) { $errors[] = TBGContext::getI18n()->__('Row %row% does not have the same number of elements as the header row', array('%row%' => $i + 1)); } } reset($data); // Check if fields are empty for ($i = 1; $i != count($data); $i++) { $activerow = $data[$i]; $activerow = html_entity_decode($activerow, ENT_QUOTES); $activerow = explode(',', $activerow); for ($j = 0; $j != count($activerow); $j++) { if ($activerow[$j] == '' || $activerow[$j] == '""') { $errors[] = TBGContext::getI18n()->__('Row %row% column %col% has no value', array('%col%' => $j + 1, '%row%' => $i + 1)); } } } if (count($errors) == 0) { // Check if fields are valid switch ($request->getParameter('type')) { case 'projects': for ($i = 1; $i != count($data); $i++) { $activerow = $data[$i]; $activerow = html_entity_decode($activerow, ENT_QUOTES); $activerow = explode(',', $activerow); // Check if project exists $key = trim($activerow[$namecol], '" '); $key = str_replace(' ', '', $key); $key = strtolower($key); $tmp = TBGProject::getByKey($key); if ($tmp !== null) { $errors[] = TBGContext::getI18n()->__('Row %row%: A project with this name already exists', array('%row%' => $i + 1)); } // First off are booleans $boolitems = array($scrum, $allow_reporting, $autoassign, $freelance, $en_builds, $en_comps, $en_editions, $show_summary); foreach ($boolitems as $boolitem) { if ($boolitem !== null && trim($activerow[$boolitem], '"') != 0 && trim($activerow[$boolitem], '"') != 1) { $errors[] = TBGContext::getI18n()->__('Row %row% column %col%: invalid value (must be 1/0)', array('%col%' => $boolitem + 1, '%row%' => $i + 1)); } } // Now identifiables $identifiableitems = array(array($qa, $qa_type), array($lead, $lead_type), array($owner, $owner_type)); foreach ($identifiableitems as $identifiableitem) { if (($identifiableitem[0] === null || $identifiableitem[1] === null) && !($identifiableitem[0] === null && $identifiableitem[1] === null)) { $errors[] = TBGContext::getI18n()->__('Row %row%: Both the type and item ID must be supplied for owner/lead/qa fields', array('%row%' => $i + 1)); continue; } if ($identifiableitem[1] !== null && trim($activerow[$identifiableitem[1]], '"') != 1 && trim($activerow[$identifiableitem[1]], '"') != 2) { $errors[] = TBGContext::getI18n()->__('Row %row% column %col%: invalid value (must be 1 for a user or 2 for a team)', array('%col%' => $identifiableitem[1] + 1, '%row%' => $i + 1)); } if ($identifiableitem[0] !== null && !is_numeric(trim($activerow[$identifiableitem[0]], '"'))) { $errors[] = TBGContext::getI18n()->__('Row %row% column %col%: invalid value (must be a number)', array('%col%' => $identifiableitem[0] + 1, '%row%' => $i + 1)); } elseif ($identifiableitem[0] !== null && is_numeric(trim($activerow[$identifiableitem[0]], '"'))) { // check if they exist switch (trim($activerow[$identifiableitem[1]], '"')) { case 1: try { TBGContext::factory()->TBGUser(trim($activerow[$identifiableitem[0]], '" ')); } catch (Exception $e) { $errors[] = TBGContext::getI18n()->__('Row %row% column %col%: user does not exist', array('%col%' => $identifiableitem[0] + 1, '%row%' => $i + 1)); } break; case 2: try { TBGContext::factory()->TBGTeam(trim($activerow[$identifiableitem[0]], '" ')); } catch (Exception $e) { $errors[] = TBGContext::getI18n()->__('Row %row% column %col%: team does not exist', array('%col%' => $identifiableitem[0] + 1, '%row%' => $i + 1)); } break; } } } // Now check client exists if ($client !== null) { if (!is_numeric(trim($activerow[$client], '"'))) { $errors[] = TBGContext::getI18n()->__('Row %row% column %col%: invalid value (must be a number)', array('%col%' => $client + 1, '%row%' => $i + 1)); } else { try { TBGContext::factory()->TBGClient(trim($activerow[$client], '" ')); } catch (Exception $e) { $errors[] = TBGContext::getI18n()->__('Row %row% column %col%: client does not exist', array('%col%' => $client + 1, '%row%' => $i + 1)); } } } // Now check if workflow exists if ($workflow_id !== null) { if (!is_numeric(trim($activerow[$workflow_id], '"'))) { $errors[] = TBGContext::getI18n()->__('Row %row% column %col%: invalid value (must be a number)', array('%col%' => $workflow_id + 1, '%row%' => $i + 1)); } else { try { TBGContext::factory()->TBGWorkflowScheme(trim($activerow[$workflow_id], '" ')); } catch (Exception $e) { $errors[] = TBGContext::getI18n()->__('Row %row% column %col%: workflow scheme does not exist', array('%col%' => $workflow_id + 1, '%row%' => $i + 1)); } } } // Now check if issuetype scheme if ($issuetype_scheme !== null) { if (!is_numeric(trim($activerow[$issuetype_scheme], '"'))) { $errors[] = TBGContext::getI18n()->__('Row %row% column %col%: invalid value (must be a number)', array('%col%' => $issuetype_scheme + 1, '%row%' => $i + 1)); } else { try { TBGContext::factory()->TBGIssuetypeScheme(trim($activerow[$issuetype_scheme], '" ')); } catch (Exception $e) { $errors[] = TBGContext::getI18n()->__('Row %row% column %col%: issuetype scheme does not exist', array('%col%' => $issuetype_scheme + 1, '%row%' => $i + 1)); } } } // Finally check if the summary type is valid. At this point, your error list has probably become so big it has eaten up all your available RAM... if ($summary_type !== null) { if (trim($activerow[$summary_type], '"') != 'issuetypes' && trim($activerow[$summary_type], '"') != 'milestones') { $errors[] = TBGContext::getI18n()->__('Row %row% column %col%: invalid value (must be \'issuetypes\' or \'milestones\')', array('%col%' => $summary_type + 1, '%row%' => $i + 1)); } } } break; case 'issues': for ($i = 1; $i != count($data); $i++) { $activerow = $data[$i]; $activerow = html_entity_decode($activerow, ENT_QUOTES); $activerow = explode(',', $activerow); // Check if project exists try { $prjtmp = TBGContext::factory()->TBGProject($activerow[$project]); } catch (Exception $e) { $errors[] = TBGContext::getI18n()->__('Row %row% column %col%: Project does not exist', array('%col%' => $project + 1, '%row%' => $i + 1)); break; } // First off are booleans $boolitems = array($state, $blocking); foreach ($boolitems as $boolitem) { if ($boolitem !== null && trim($activerow[$boolitem], '"') != 0 && trim($activerow[$boolitem], '"') != 1) { $errors[] = TBGContext::getI18n()->__('Row %row% column %col%: invalid value (must be 1/0)', array('%col%' => $boolitem + 1, '%row%' => $i + 1)); } } // Now numerics $numericitems = array($votes, $percentage); foreach ($numericitems as $numericitem) { if ($numericitem !== null && !is_numeric(trim($activerow[$numericitem], '"'))) { $errors[] = TBGContext::getI18n()->__('Row %row% column %col%: invalid value (must be a number)', array('%col%' => $numericitem + 1, '%row%' => $i + 1)); } } // Percentage must be 0-100 if ($numericitem !== null && (trim($activerow[$percentage], '"') < 0 || trim($activerow[$percentage], '"') > 100)) { $errors[] = TBGContext::getI18n()->__('Row %row% column %col%: Percentage must be from 0 to 100 inclusive', array('%col%' => $percentage + 1, '%row%' => $i + 1)); } // Now identifiables $identifiableitems = array(array($owner, $owner_type), array($assigned, $assigned_type)); foreach ($identifiableitems as $identifiableitem) { if (($identifiableitem[0] === null || $identifiableitem[1] === null) && !($identifiableitem[0] === null && $identifiableitem[1] === null)) { $errors[] = TBGContext::getI18n()->__('Row %row%: Both the type and item ID must be supplied for owner/lead/qa fields', array('%row%' => $i + 1)); continue; } if ($identifiableitem[1] !== null && trim($activerow[$identifiableitem[1]], '"') != 1 && trim($activerow[$identifiableitem[1]], '"') != 2) { $errors[] = TBGContext::getI18n()->__('Row %row% column %col%: invalid value (must be 1 for a user or 2 for a team)', array('%col%' => $identifiableitem[1] + 1, '%row%' => $i + 1)); } if ($identifiableitem[0] !== null && !is_numeric(trim($activerow[$identifiableitem[0]], '"'))) { $errors[] = TBGContext::getI18n()->__('Row %row% column %col%: invalid value (must be a number)', array('%col%' => $identifiableitem[0] + 1, '%row%' => $i + 1)); } elseif ($identifiableitem[0] !== null && is_numeric(trim($activerow[$identifiableitem[0]], '"'))) { // check if they exist switch (trim($activerow[$identifiableitem[1]], '"')) { case 1: try { TBGContext::factory()->TBGUser(trim($activerow[$identifiableitem[0]], '" ')); } catch (Exception $e) { $errors[] = TBGContext::getI18n()->__('Row %row% column %col%: user does not exist', array('%col%' => $identifiableitem[0] + 1, '%row%' => $i + 1)); } break; case 2: try { TBGContext::factory()->TBGTeam(trim($activerow[$identifiableitem[0]], '" ')); } catch (Exception $e) { $errors[] = TBGContext::getI18n()->__('Row %row% column %col%: team does not exist', array('%col%' => $identifiableitem[0] + 1, '%row%' => $i + 1)); } break; } } } // Now check user exists for postedby if ($posted_by !== null) { if (!is_numeric(trim($activerow[$posted_by], '"'))) { $errors[] = TBGContext::getI18n()->__('Row %row% column %col%: invalid value (must be a number)', array('%col%' => $posted_by + 1, '%row%' => $i + 1)); } else { try { TBGContext::factory()->TBGUser(trim($activerow[$posted_by], '" ')); } catch (Exception $e) { $errors[] = TBGContext::getI18n()->__('Row %row% column %col%: user does not exist', array('%col%' => $posted_by + 1, '%row%' => $i + 1)); } } } // Now check milestone exists and is valid if ($milestone !== null) { if (!is_numeric(trim($activerow[$milestone], '"'))) { $errors[] = TBGContext::getI18n()->__('Row %row% column %col%: invalid value (must be a number)', array('%col%' => $milestone + 1, '%row%' => $i + 1)); } else { try { $milestonetmp = TBGContext::factory()->TBGMilestone(trim($activerow[$milestone], '" ')); if ($milestonetmp->getProject()->getID() != $activerow[$project]) { $errors[] = TBGContext::getI18n()->__('Row %row% column %col%: milestone does not apply to the specified project', array('%col%' => $milestone + 1, '%row%' => $i + 1)); } } catch (Exception $e) { $errors[] = TBGContext::getI18n()->__('Row %row% column %col%: milestone does not exist', array('%col%' => $milestone + 1, '%row%' => $i + 1)); } } } // status if ($status !== null) { if (!is_numeric(trim($activerow[$status], '"'))) { $errors[] = TBGContext::getI18n()->__('Row %row% column %col%: invalid value (must be a number)', array('%col%' => $status + 1, '%row%' => $i + 1)); } else { try { TBGContext::factory()->TBGStatus(trim($activerow[$status], '" ')); } catch (Exception $e) { $errors[] = TBGContext::getI18n()->__('Row %row% column %col%: status does not exist', array('%col%' => $status + 1, '%row%' => $i + 1)); } } } // resolution if ($resolution !== null) { if (!is_numeric(trim($activerow[$resolution], '"'))) { $errors[] = TBGContext::getI18n()->__('Row %row% column %col%: invalid value (must be a number)', array('%col%' => $resolution + 1, '%row%' => $i + 1)); } else { try { TBGContext::factory()->TBGResolution(trim($activerow[$resolution], '" ')); } catch (Exception $e) { $errors[] = TBGContext::getI18n()->__('Row %row% column %col%: resolution does not exist', array('%col%' => $resolution + 1, '%row%' => $i + 1)); } } } // priority if ($priority !== null) { if (!is_numeric(trim($activerow[$priority], '"'))) { $errors[] = TBGContext::getI18n()->__('Row %row% column %col%: invalid value (must be a number)', array('%col%' => $priority + 1, '%row%' => $i + 1)); } else { try { TBGContext::factory()->TBGPriority(trim($activerow[$priority], '" ')); } catch (Exception $e) { $errors[] = TBGContext::getI18n()->__('Row %row% column %col%: priority does not exist', array('%col%' => $priority + 1, '%row%' => $i + 1)); } } } // category if ($category !== null) { if (!is_numeric(trim($activerow[$category], '"'))) { $errors[] = TBGContext::getI18n()->__('Row %row% column %col%: invalid value (must be a number)', array('%col%' => $category + 1, '%row%' => $i + 1)); } else { try { TBGContext::factory()->TBGCategory(trim($activerow[$category], '" ')); } catch (Exception $e) { $errors[] = TBGContext::getI18n()->__('Row %row% column %col%: category does not exist', array('%col%' => $category + 1, '%row%' => $i + 1)); } } } // severity if ($severity !== null) { if (!is_numeric(trim($activerow[$severity], '"'))) { $errors[] = TBGContext::getI18n()->__('Row %row% column %col%: invalid value (must be a number)', array('%col%' => $severity + 1, '%row%' => $i + 1)); } else { try { TBGContext::factory()->TBGSeverity(trim($activerow[$severity], '" ')); } catch (Exception $e) { $errors[] = TBGContext::getI18n()->__('Row %row% column %col%: severity does not exist', array('%col%' => $severity + 1, '%row%' => $i + 1)); } } } // reproducability if ($reproducability !== null) { if (!is_numeric(trim($activerow[$reproducability], '"'))) { $errors[] = TBGContext::getI18n()->__('Row %row% column %col%: invalid value (must be a number)', array('%col%' => $reproducability + 1, '%row%' => $i + 1)); } else { try { TBGContext::factory()->TBGReproducability(trim($activerow[$reproducability], '" ')); } catch (Exception $e) { $errors[] = TBGContext::getI18n()->__('Row %row% column %col%: reproducability does not exist', array('%col%' => $reproducability + 1, '%row%' => $i + 1)); } } } // type if ($issue_type !== null) { if (!is_numeric(trim($activerow[$issue_type], '"'))) { $errors[] = TBGContext::getI18n()->__('Row %row% column %col%: invalid value (must be a number)', array('%col%' => $issue_type + 1, '%row%' => $i + 1)); } else { try { $typetmp = TBGContext::factory()->TBGIssuetype(trim($activerow[$issue_type], '" ')); if (!$prjtmp->getIssuetypeScheme()->isSchemeAssociatedWithIssuetype($typetmp)) { $errors[] = TBGContext::getI18n()->__('Row %row% column %col%: this project does not support issues of this type (%type%)', array('%type%' => $typetmp->getName(), '%col%' => $issue_type + 1, '%row%' => $i + 1)); } } catch (Exception $e) { $errors[] = TBGContext::getI18n()->__('Row %row% column %col%: issue type does not exist', array('%col%' => $issue_type + 1, '%row%' => $i + 1)); } } } } break; } } // Handle errors if (count($errors) != 0) { $errordiv = '<ul>'; foreach ($errors as $error) { $errordiv .= '<li>' . $error . '</li>'; } $errordiv .= '</ul>'; $this->getResponse()->setHttpStatus(400); return $this->renderJSON(array('failed' => true, 'errordetail' => $errordiv, 'error' => TBGContext::getI18n()->__('Errors occured while importing, see the error list in the import screen for further details'))); } } catch (Exception $e) { $this->getResponse()->setHttpStatus(400); return $this->renderJSON(array('failed' => true, 'errordetail' => $e->getMessage(), 'error' => $e->getMessage())); } if ($request->getParameter('csv_dry_run')) { return $this->renderJSON(array('failed' => false, 'message' => TBGContext::getI18n()->__('Dry-run successful, you can now uncheck the dry-run box and import your data.'))); } else { switch ($request->getParameter('type')) { case 'clients': for ($i = 1; $i != count($data); $i++) { try { $activerow = $data[$i]; $activerow = html_entity_decode($activerow, ENT_QUOTES); $activerow = explode(',', $activerow); $client = new TBGClient(); $client->setName(trim($activerow[$namecol], '" ')); if ($emailcol !== null) { $client->setEmail(trim($activerow[$emailcol], '" ')); } if ($websitecol !== null) { $client->setWebsite(trim($activerow[$websitecol], '" ')); } if ($faxcol !== null) { $client->setFax(trim($activerow[$faxcol], '" ')); } if ($telephonecol !== null) { $client->setTelephone(trim($activerow[$telephonecol], '" ')); } $client->save(); } catch (Exception $e) { $errors[] = TBGContext::getI18n()->__('Row %row% failed: %err%', array('%row%' => $i + 1, '%err%' => $e->getMessage())); } } break; case 'projects': for ($i = 1; $i != count($data); $i++) { try { $activerow = $data[$i]; $activerow = html_entity_decode($activerow, ENT_QUOTES); $activerow = explode(',', $activerow); $project = new TBGProject(); $project->setName(trim($activerow[$namecol], '" ')); if ($prefix !== null) { $project->setPrefix(trim($activerow[$prefix], '" ')); $project->setUsePrefix(true); } if ($scrum !== null) { if (trim($activerow[$websitecol], '"') == '1') { $project->setUseScrum(true); } } if ($owner !== null && $owner_type !== null) { switch (trim($activerow[$owner_type], '"')) { case TBGIdentifiableClass::TYPE_USER: $user = new TBGUser(trim($activerow[$owner], '" ')); $project->setOwner($user); break; case TBGIdentifiableClass::TYPE_TEAM: $team = new TBGTeam(trim($activerow[$owner], '" ')); $project->setOwner($team); break; } } if ($lead !== null && $lead_type !== null) { switch (trim($activerow[$lead_type], '"')) { case TBGIdentifiableClass::TYPE_USER: $user = new TBGUser(trim($activerow[$lead], '" ')); $project->setLeader($user); break; case TBGIdentifiableClass::TYPE_TEAM: $team = new TBGTeam(trim($activerow[$lead], '" ')); $project->setLeader($team); break; } } if ($qa !== null && $qa_type !== null) { switch (trim($activerow[$qa_type], '"')) { case TBGIdentifiableClass::TYPE_USER: $user = new TBGUser(trim($activerow[$qa], '" ')); $project->setQaResponsible($user); break; case TBGIdentifiableClass::TYPE_TEAM: $team = new TBGTeam(trim($activerow[$qa], '" ')); $project->setQaResponsible($team); break; } } if ($descr !== null) { $project->setDescription(trim($activerow[$descr], '" ')); } if ($doc_url !== null) { $project->setDocumentationUrl(trim($activerow[$doc_url], '" ')); } if ($freelance !== null) { if (trim($activerow[$freelance], '"') == '1') { $project->setChangeIssuesWithoutWorkingOnThem(true); } } if ($en_builds !== null) { if (trim($activerow[$en_builds], '"') == '1') { $project->setBuildsEnabled(true); } } if ($en_comps !== null) { if (trim($activerow[$en_comps], '"') == '1') { $project->setComponentsEnabled(true); } } if ($en_editions !== null) { if (trim($activerow[$en_editions], '"') == '1') { $project->setEditionsEnabled(true); } } if ($workflow_id !== null) { $workflow = TBGContext::factory()->TBGWorkflowScheme(trim($activerow[$workflow_id], '" ')); $project->setWorkflowScheme($workflow); } if ($client !== null) { $client_object = TBGContext::factory()->TBGWorkflowScheme(trim($activerow[$client], '" ')); $project->setClient($client_object); } if ($show_summary !== null) { if (trim($activerow[$show_summary], '"') == '1') { $project->setFrontpageSummaryVisibility(true); } } if ($summary_type !== null) { $project->setFrontpageSummaryType(trim($activerow[$summary_type], '" ')); } if ($issuetype_scheme !== null) { $project->setIssuetypeScheme(TBGContext::factory()->TBGIssuetypeScheme(trim($activerow[$issuetype_scheme], '"'))); } if ($allow_reporting !== null) { $project->setLocked(trim($activerow[$allow_reporting], '" ')); } if ($autoassign !== null) { $project->setAutoassign(trim($activerow[$autoassign], '" ')); } $project->save(); } catch (Exception $e) { $errors[] = TBGContext::getI18n()->__('Row %row% failed: %err%', array('%row%' => $i + 1, '%err%' => $e->getMessage())); } } break; case 'issues': for ($i = 1; $i != count($data); $i++) { try { $activerow = $data[$i]; $activerow = html_entity_decode($activerow, ENT_QUOTES); $activerow = explode(',', $activerow); $issue = new TBGIssue(); $issue->setTitle(trim($activerow[$title], '" ')); $issue->setProject(trim($activerow[$project], '" ')); $issue->setIssuetype(trim($activerow[$issue_type], '" ')); if ($issue_type !== null) { $issue->setIssuetype(trim($activerow[$issue_type], '" ')); } if ($descr !== null) { $issue->setDescription(trim($activerow[$descr], '" ')); } if ($repro !== null) { $issue->setReproduction(trim($activerow[$repro], '" ')); } if ($state !== null) { $issue->setState(trim($activerow[$state], '" ')); } if ($status !== null) { $issue->setStatus(trim($activerow[$status], '" ')); } if ($posted_by !== null) { $issue->setPostedBy(TBGContext::factory()->TBGUser(trim($activerow[$posted_by], '"'))); } if ($owner !== null && $owner_type !== null) { switch (trim($activerow[$owner_type], '"')) { case TBGIdentifiableClass::TYPE_USER: $user = new TBGUser(trim($activerow[$owner], '" ')); $issue->setOwner($user); break; case TBGIdentifiableClass::TYPE_TEAM: $team = new TBGTeam(trim($activerow[$owner], '" ')); $issue->setOwner($team); break; } } if ($assigned !== null && $assigned_type !== null) { switch (trim($activerow[$assigned_type], '"')) { case TBGIdentifiableClass::TYPE_USER: $user = new TBGUser(trim($activerow[$assigned], '" ')); $issue->setAssignee($user); break; case TBGIdentifiableClass::TYPE_TEAM: $team = new TBGTeam(trim($activerow[$assigned], '" ')); $issue->setAssignee($team); break; } } if ($resolution !== null) { $issue->setResolution(trim($activerow[$resolution], '" ')); } if ($priority !== null) { $issue->setPriority(trim($activerow[$priority], '" ')); } if ($category !== null) { $issue->setCategory(trim($activerow[$category], '" ')); } if ($blocking !== null) { $issue->setBlocking(trim($activerow[$blocking], '" ')); } if ($severity !== null) { $issue->setSeverity(trim($activerow[$severity], '" ')); } if ($reproducability !== null) { $issue->setReproducability(trim($activerow[$reproducability], '" ')); } if ($votes !== null) { $issue->setVotes(trim($activerow[$votes], '" ')); } if ($percentage !== null) { $issue->setPercentage(trim($activerow[$percentage], '" ')); } if ($milestone !== null) { $issue->setMilestone(trim($activerow[$milestone], '" ')); } $issue->save(); } catch (Exception $e) { $errors[] = TBGContext::getI18n()->__('Row %row% failed: %err%', array('%row%' => $i + 1, '%err%' => $e->getMessage())); } } break; } // Handle errors if (count($errors) != 0) { $errordiv = '<ul>'; foreach ($errors as $error) { $errordiv .= '<li>' . $error . '</li>'; } $errordiv .= '</ul>'; $this->getResponse()->setHttpStatus(400); return $this->renderJSON(array('failed' => true, 'errordetail' => $errordiv, 'error' => TBGContext::getI18n()->__('Errors occured while importing, see the error list in the import screen for further details'))); } else { return $this->renderJSON(array('failed' => false, 'message' => TBGContext::getI18n()->__('Successfully imported %num% rows!', array('%num%' => count($data) - 1)))); } } }
protected function _populateIssueCountsByMilestone($milestone_id, $exclude_tasks = false) { if ($this->_issuecounts === null) { $this->_issuecounts = array(); } if (!array_key_exists('milestone', $this->_issuecounts)) { $this->_issuecounts['milestone'] = array(); } if (!array_key_exists($milestone_id, $this->_issuecounts['milestone'])) { list($this->_issuecounts['milestone'][$milestone_id]['closed'], $this->_issuecounts['milestone'][$milestone_id]['open']) = TBGIssue::getIssueCountsByProjectIDandMilestone($this->getID(), $milestone_id, $exclude_tasks); } }
public function perform(TBGIssue $issue, $request = null) { switch ($this->_action_type) { case self::ACTION_ASSIGN_ISSUE_SELF: $issue->setAssignee(TBGContext::getUser()); break; case self::ACTION_SET_STATUS: if ($this->getTargetValue()) { $issue->setStatus(TBGContext::factory()->TBGStatus((int) $this->getTargetValue())); } else { $issue->setStatus($request['status_id']); } break; case self::ACTION_SET_MILESTONE: if ($this->getTargetValue()) { $issue->setMilestone(TBGContext::factory()->TBGMilestone((int) $this->getTargetValue())); } else { $issue->setMilestone($request['milestone_id']); } break; case self::ACTION_CLEAR_PRIORITY: $issue->setPriority(null); break; case self::ACTION_SET_PRIORITY: if ($this->getTargetValue()) { $issue->setPriority(TBGContext::factory()->TBGPriority((int) $this->getTargetValue())); } else { $issue->setPriority($request['priority_id']); } break; case self::ACTION_CLEAR_PERCENT: $issue->setPercentCompleted(0); break; case self::ACTION_SET_PERCENT: if ($this->getTargetValue()) { $issue->setPercentCompleted((int) $this->getTargetValue()); } else { $issue->setPercentCompleted((int) $request['percent_complete_id']); } break; case self::ACTION_CLEAR_DUPLICATE: $issue->setDuplicateOf(null); break; case self::ACTION_SET_DUPLICATE: $issue->setDuplicateOf($request['duplicate_issue_id']); break; case self::ACTION_CLEAR_RESOLUTION: $issue->setResolution(null); break; case self::ACTION_SET_RESOLUTION: if ($this->getTargetValue()) { $issue->setResolution(TBGContext::factory()->TBGResolution((int) $this->getTargetValue())); } else { $issue->setResolution($request['resolution_id']); } break; case self::ACTION_CLEAR_REPRODUCABILITY: $issue->setReproducability(null); break; case self::ACTION_SET_REPRODUCABILITY: if ($this->getTargetValue()) { $issue->setReproducability(TBGContext::factory()->TBGReproducability((int) $this->getTargetValue())); } else { $issue->setReproducability($request['reproducability_id']); } break; case self::ACTION_CLEAR_ASSIGNEE: $issue->clearAssignee(); break; case self::ACTION_ASSIGN_ISSUE: if ($this->getTargetValue()) { $target_details = explode('_', $this->_target_value); if ($target_details[0] == 'user') { $assignee = TBGUser::getB2DBTable()->selectById((int) $target_details[1]); } else { $assignee = TBGTeam::getB2DBTable()->selectById((int) $target_details[1]); } $issue->setAssignee($assignee); } else { $assignee = null; switch ($request['assignee_type']) { case 'user': $assignee = TBGUser::getB2DBTable()->selectById((int) $request['assignee_id']); break; case 'team': $assignee = TBGTeam::getB2DBTable()->selectById((int) $request['assignee_id']); break; } if ((bool) $request->getParameter('assignee_teamup', false) && $assignee instanceof TBGUser && $assignee->getID() != TBGContext::getUser()->getID()) { $team = new TBGTeam(); $team->setName($assignee->getBuddyname() . ' & ' . TBGContext::getUser()->getBuddyname()); $team->setOndemand(true); $team->save(); $team->addMember($assignee); $team->addMember(TBGContext::getUser()); $assignee = $team; } $issue->setAssignee($assignee); } break; case self::ACTION_USER_START_WORKING: $issue->clearUserWorkingOnIssue(); if ($issue->getAssignee() instanceof TBGTeam && $issue->getAssignee()->isOndemand()) { $members = $issue->getAssignee()->getMembers(); $issue->startWorkingOnIssue(array_shift($members)); } elseif ($issue->getAssignee() instanceof TBGUser) { $issue->startWorkingOnIssue($issue->getAssignee()); } break; case self::ACTION_USER_STOP_WORKING: if ($request->getParameter('did', 'nothing') == 'nothing') { $issue->clearUserWorkingOnIssue(); } elseif ($request->getParameter('did', 'nothing') == 'this') { $times = array(); if ($request['timespent_manual']) { $times = TBGIssue::convertFancyStringToTime($request['timespent_manual']); } elseif ($request['timespent_specified_type']) { $times = array('points' => 0, 'hours' => 0, 'days' => 0, 'weeks' => 0, 'months' => 0); $times[$request['timespent_specified_type']] = $request['timespent_specified_value']; } if (array_sum($times) > 0) { $times['hours'] *= 100; $spenttime = new TBGIssueSpentTime(); $spenttime->setIssue($issue); $spenttime->setUser(TBGContext::getUser()); $spenttime->setSpentPoints($times['points']); $spenttime->setSpentHours($times['hours']); $spenttime->setSpentDays($times['days']); $spenttime->setSpentWeeks($times['weeks']); $spenttime->setSpentMonths($times['months']); $spenttime->setActivityType($request['timespent_activitytype']); $spenttime->setComment($request['timespent_comment']); $spenttime->save(); } $issue->clearUserWorkingOnIssue(); } else { $issue->stopWorkingOnIssue(); } break; } }
<a href="javascript:void(0);" onclick="setField('<?php echo make_url('issue_setfield', array('project_key' => $issue->getProject()->getKey(), 'issue_id' => $issue->getID(), 'field' => 'pain_effect', 'pain_effect_id' => 0)); ?> ', 'pain_effect');"><?php echo __('Clear effect'); ?> </a><br> </div> <div class="dropdown_content"> <?php echo __('%clear_the_effect% or click to select a new effect', array('%clear_the_effect%' => '')); ?> :<br> <ul class="choices"> <?php foreach (TBGIssue::getPainTypesOrLabel('pain_effect') as $choice_id => $choice) { ?> <li> <?php //echo image_tag('icon_' . $field . '.png', array('style' => 'float: left; margin-right: 5px;')); ?> <a href="javascript:void(0);" onclick="setField('<?php echo make_url('issue_setfield', array('project_key' => $issue->getProject()->getKey(), 'issue_id' => $issue->getID(), 'field' => 'pain_effect', 'pain_effect_id' => $choice_id)); ?> ', 'pain_effect');"><?php echo $choice; ?> </a> </li> <?php }
public function perform(TBGIssue $issue, $request = null) { switch ($this->_action_type) { case self::ACTION_ASSIGN_ISSUE_SELF: $issue->setAssignee(TBGContext::getUser()); break; case self::ACTION_SET_STATUS: if ($this->getTargetValue()) { $issue->setStatus(TBGContext::factory()->TBGStatus((int) $this->getTargetValue())); } else { $issue->setStatus($request->getParameter('status_id')); } break; case self::ACTION_SET_MILESTONE: if ($this->getTargetValue()) { $issue->setMilestone(TBGContext::factory()->TBGMilestone((int) $this->getTargetValue())); } else { $issue->setMilestone($request->getParameter('milestone_id')); } break; case self::ACTION_CLEAR_PRIORITY: $issue->setPriority(null); break; case self::ACTION_SET_PRIORITY: if ($this->getTargetValue()) { $issue->setPriority(TBGContext::factory()->TBGPriority((int) $this->getTargetValue())); } else { $issue->setPriority($request->getParameter('priority_id')); } break; case self::ACTION_CLEAR_PERCENT: $issue->setPercentCompleted(0); break; case self::ACTION_SET_PERCENT: if ($this->getTargetValue()) { $issue->setPercentCompleted((int) $this->getTargetValue()); } else { $issue->setPercentCompleted((int) $request->getParameter('percent_complete_id')); } break; case self::ACTION_CLEAR_RESOLUTION: $issue->setResolution(null); break; case self::ACTION_SET_RESOLUTION: if ($this->getTargetValue()) { $issue->setResolution(TBGContext::factory()->TBGResolution((int) $this->getTargetValue())); } else { $issue->setResolution($request->getParameter('resolution_id')); } break; case self::ACTION_CLEAR_REPRODUCABILITY: $issue->setReproducability(null); break; case self::ACTION_SET_REPRODUCABILITY: if ($this->getTargetValue()) { $issue->setReproducability(TBGContext::factory()->TBGReproducability((int) $this->getTargetValue())); } else { $issue->setReproducability($request->getParameter('reproducability_id')); } break; case self::ACTION_CLEAR_ASSIGNEE: $issue->unsetAssignee(); break; case self::ACTION_ASSIGN_ISSUE: if ($this->getTargetValue()) { $issue->setAssignee(TBGContext::factory()->TBGUser((int) $this->getTargetValue())); } else { $assignee = null; switch ($request->getParameter('assignee_type')) { case TBGIdentifiableClass::TYPE_USER: $assignee = TBGContext::factory()->TBGUser($request->getParameter('assignee_id')); break; case TBGIdentifiableClass::TYPE_TEAM: $assignee = TBGContext::factory()->TBGTeam($request->getParameter('assignee_id')); break; } if ((bool) $request->getParameter('assignee_teamup', false)) { $team = new TBGTeam(); $team->setName($assignee->getBuddyname() . ' & ' . TBGContext::getUser()->getBuddyname()); $team->setOndemand(true); $team->save(); $team->addMember($assignee); $team->addMember(TBGContext::getUser()); $assignee = $team; } $issue->setAssignee($assignee); } break; case self::ACTION_USER_START_WORKING: $issue->clearUserWorkingOnIssue(); if ($issue->getAssignee() instanceof TBGTeam && $issue->getAssignee()->isOndemand()) { $members = $issue->getAssignee()->getMembers(); $issue->startWorkingOnIssue(array_shift($members)); } else { $issue->startWorkingOnIssue($issue->getAssignee()); } break; case self::ACTION_USER_STOP_WORKING: if ($request->getParameter('did', 'nothing') == 'nothing') { $issue->clearUserWorkingOnIssue(); } else { $issue->stopWorkingOnIssue(); } break; } }
protected function _parse_issuelink($matches) { $theIssue = TBGIssue::getIssueFromLink($matches[0]); $output = ''; $classname = ''; if ($theIssue instanceof TBGIssue && ($theIssue->isClosed() || $theIssue->isDeleted())) { $classname = 'closed'; } if ($theIssue instanceof TBGIssue) { $output = ' ' . link_tag(make_url('viewissue', array('issue_no' => $theIssue->getFormattedIssueNo(false), 'project_key' => $theIssue->getProject()->getKey())), $theIssue->getFormattedTitle(), array('class' => $classname)); } else { $output = $matches[1]; } return $output; }
public static function processCommit(TBGProject $project, $commit_msg, $old_rev, $new_rev, $date = null, $changed, $author, $branch = null) { $output = ''; TBGContext::setCurrentProject($project); if ($project->isArchived()) { return; } try { TBGContext::getI18n(); } catch (Exception $e) { TBGContext::reinitializeI18n(null); } // Is VCS Integration enabled? if (TBGSettings::get('vcs_mode_' . $project->getID(), 'vcs_integration') == TBGVCSIntegration::MODE_DISABLED) { $output .= '[VCS ' . $project->getKey() . '] This project does not use VCS Integration' . "\n"; return $output; } // Parse the commit message, and obtain the issues and transitions for issues. $parsed_commit = TBGIssue::getIssuesFromTextByRegex($commit_msg); $issues = $parsed_commit["issues"]; $transitions = $parsed_commit["transitions"]; // If no issues exist, we may not be able to continue // if (count($issues) == 0) // { // $output .= '[VCS '.$project->getKey().'] This project only accepts commits which affect issues' . "\n"; // return $output; // } // Build list of affected files $file_lines = preg_split('/[\\n\\r]+/', $changed); $files = array(); foreach ($file_lines as $aline) { $action = mb_substr($aline, 0, 1); if ($action == "A" || $action == "U" || $action == "D" || $action == "M") { $theline = trim(mb_substr($aline, 1)); $files[] = array($action, $theline); } } // Find author of commit, fallback is guest /* * Some VCSes use a different format of storing the committer's name. Systems like bzr, git and hg use the format * Joe Bloggs <*****@*****.**>, instead of a classic username. Therefore a user will be found via 4 queries: * a) First we extract the email if there is one, and find a user with that email * b) If one is not found - or if no email was specified, then instead test against the real name (using the name part if there was an email) * c) the username or full name is checked against the friendly name field * d) and if we still havent found one, then we check against the username * e) and if we STILL havent found one, we use the guest user */ if (preg_match("/(?<=<)(.*)(?=>)/", $author, $matches)) { $email = $matches[0]; // a) $user = TBGUsersTable::getTable()->getByEmail($email); if (!$user instanceof TBGUser) { // Not found by email preg_match("/(?<=^)(.*)(?= <)/", $author, $matches); $author = $matches[0]; } } // b) if (!$user instanceof TBGUser) { $user = TBGUsersTable::getTable()->getByRealname($author); } // c) if (!$user instanceof TBGUser) { $user = TBGUsersTable::getTable()->getByBuddyname($author); } // d) if (!$user instanceof TBGUser) { $user = TBGUsersTable::getTable()->getByUsername($author); } // e) if (!$user instanceof TBGUser) { $user = TBGSettings::getDefaultUser(); } TBGContext::setUser($user); TBGSettings::forceSettingsReload(); TBGContext::cacheAllPermissions(); $output .= '[VCS ' . $project->getKey() . '] Commit to be logged by user ' . $user->getName() . "\n"; if ($date == null) { $date = NOW; } // Create the commit data $commit = new TBGVCSIntegrationCommit(); $commit->setAuthor($user); $commit->setDate($date); $commit->setLog($commit_msg); $commit->setPreviousRevision($old_rev); $commit->setRevision($new_rev); $commit->setProject($project); if ($branch !== null) { $data = 'branch:' . $branch; $commit->setMiscData($data); } $commit->save(); $output .= '[VCS ' . $project->getKey() . '] Commit logged with revision ' . $commit->getRevision() . "\n"; // Iterate over affected issues and update them. foreach ($issues as $issue) { $inst = new TBGVCSIntegrationIssueLink(); $inst->setIssue($issue); $inst->setCommit($commit); $inst->save(); // Process all commit-message transitions for an issue. foreach ($transitions[$issue->getFormattedIssueNo()] as $transition) { if (TBGSettings::get('vcs_workflow_' . $project->getID(), 'vcs_integration') == TBGVCSIntegration::WORKFLOW_ENABLED) { TBGContext::setUser($user); TBGSettings::forceSettingsReload(); TBGContext::cacheAllPermissions(); if ($issue->isWorkflowTransitionsAvailable()) { // Go through the list of possible transitions for an issue. Only // process transitions that are applicable to issue's workflow. foreach ($issue->getAvailableWorkflowTransitions() as $possible_transition) { if (mb_strtolower($possible_transition->getName()) == mb_strtolower($transition[0])) { $output .= '[VCS ' . $project->getKey() . '] Running transition ' . $transition[0] . ' on issue ' . $issue->getFormattedIssueNo() . "\n"; // String representation of parameters. Used for log message. $parameters_string = ""; // Iterate over the list of this transition's parameters, and // set them. foreach ($transition[1] as $parameter => $value) { $parameters_string .= "{$parameter}={$value} "; switch ($parameter) { case 'resolution': if (($resolution = TBGResolution::getResolutionByKeyish($value)) instanceof TBGResolution) { TBGContext::getRequest()->setParameter('resolution_id', $resolution->getID()); } break; case 'status': if (($status = TBGStatus::getStatusByKeyish($value)) instanceof TBGStatus) { TBGContext::getRequest()->setParameter('status_id', $status->getID()); } break; } } // Run the transition. $possible_transition->transitionIssueToOutgoingStepWithoutRequest($issue); // Log an informative message about the transition. $output .= '[VCS ' . $project->getKey() . '] Ran transition ' . $possible_transition->getName() . ' with parameters \'' . $parameters_string . '\' on issue ' . $issue->getFormattedIssueNo() . "\n"; } } } } } $issue->addSystemComment(TBGContext::getI18n()->__('This issue has been updated with the latest changes from the code repository.<source>%commit_msg</source>', array('%commit_msg' => $commit_msg)), $user->getID()); $output .= '[VCS ' . $project->getKey() . '] Updated issue ' . $issue->getFormattedIssueNo() . "\n"; } // Create file links foreach ($files as $afile) { // index 0 is action, index 1 is file $inst = new TBGVCSIntegrationFile(); $inst->setAction($afile[0]); $inst->setFile($afile[1]); $inst->setCommit($commit); $inst->save(); $output .= '[VCS ' . $project->getKey() . '] Added with action ' . $afile[0] . ' file ' . $afile[1] . "\n"; } TBGEvent::createNew('vcs_integration', 'new_commit')->trigger(array('commit' => $commit)); return $output; }
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; }
public function addNewCommit($project, $commit_msg, $old_rev, $new_rev, $date = null, $changed, $author) { /* Find issues to update */ $fixes_grep = "#((bug|issue|ticket|fix|fixes|fixed|fixing|applies to|closes|references|ref|addresses|re|see|according to|also see)\\s\\#?(([A-Z0-9]+\\-)?\\d+))#ie"; $output = ''; $f_issues = array(); try { TBGContext::getI18n(); } catch (Exception $e) { TBGContext::reinitializei18n(); } try { $project = new TBGProject($project); } catch (Exception $e) { return TBGContext::getI18n()->__('Error: Invalid project ID'); } if (preg_match_all($fixes_grep, $commit_msg, $f_issues)) { // Github if (is_array($changed)) { $entries = $changed; $changed = ''; // Now handle changed files foreach ($entries[0] as $file) { $changed .= 'M' . $file . "\n"; } // Now handle new files foreach ($entries[1] as $file) { $changed .= 'A' . $file . "\n"; } // Now handle deleted files foreach ($entries[2] as $file) { $changed .= 'D' . $file . "\n"; } } $f_issues = array_unique($f_issues[3]); $file_lines = preg_split('/[\\n\\r]+/', $changed); $files = array(); foreach ($file_lines as $aline) { $action = substr($aline, 0, 1); if ($action == "A" || $action == "U" || $action == "D" || $action == "M") { $theline = trim(substr($aline, 1)); $files[] = array($action, $theline); } } foreach ($f_issues as $issue_no) { TBGContext::setCurrentProject($project); $theIssue = TBGIssue::getIssueFromLink($issue_no, true); if ($theIssue instanceof TBGIssue) { $uid = 0; /* * Some VCSes use a different format of storing the committer's name. Systems like bzr, git and hg use the format * Joe Bloggs <*****@*****.**>, instead of a classic username. Therefore a user will be found via 4 queries: * a) First we extract the email if there is one, and find a user with that email * b) If one is not found - or if no email was specified, then instead test against the real name (using the name part if there was an email) * c) the username or full name is checked against the friendly name field * d) and if we still havent found one, then we check against the username * e) and if we STILL havent found one, we just say the user is id 0 (unknown user). */ if (preg_match("/(?<=<)(.*)(?=>)/", $author, $matches)) { $email = $matches[0]; // a) $crit = new B2DBCriteria(); $crit->setFromTable(TBGUsersTable::getTable()); $crit->addSelectionColumn(TBGUsersTable::ID); $crit->addWhere(TBGUsersTable::EMAIL, $email); $row = TBGUsersTable::getTable()->doSelectOne($crit); if ($row != null) { $uid = $row->get(TBGUsersTable::ID); } else { // Not found by email preg_match("/(?<=^)(.*)(?= <)/", $author, $matches); $author = $matches[0]; } } // b) if ($uid == 0) { $crit = new B2DBCriteria(); $crit->setFromTable(TBGUsersTable::getTable()); $crit->addSelectionColumn(TBGUsersTable::ID); $crit->addWhere(TBGUsersTable::REALNAME, $author); $row = TBGUsersTable::getTable()->doSelectOne($crit); if ($row != null) { $uid = $row->get(TBGUsersTable::ID); } } // c) if ($uid == 0) { $crit = new B2DBCriteria(); $crit->setFromTable(TBGUsersTable::getTable()); $crit->addSelectionColumn(TBGUsersTable::ID); $crit->addWhere(TBGUsersTable::BUDDYNAME, $author); $row = TBGUsersTable::getTable()->doSelectOne($crit); if ($row != null) { $uid = $row->get(TBGUsersTable::ID); } } // d) if ($uid == 0) { $crit = new B2DBCriteria(); $crit->setFromTable(TBGUsersTable::getTable()); $crit->addSelectionColumn(TBGUsersTable::ID); $crit->addWhere(TBGUsersTable::UNAME, $author); $row = TBGUsersTable::getTable()->doSelectOne($crit); if ($row != null) { $uid = $row->get(TBGUsersTable::ID); } } $theIssue->addSystemComment(TBGContext::getI18n()->__('Issue updated from code repository'), TBGContext::getI18n()->__('This issue has been updated with the latest changes from the code repository.<source>%commit_msg%</source>', array('%commit_msg%' => $commit_msg)), $uid); foreach ($files as $afile) { if ($date == null) { $date = time(); } TBGVCSIntegrationTable::addEntry($theIssue->getID(), $afile[0], $commit_msg, $afile[1], $new_rev, $old_rev, $uid, $date); } $output .= 'Updated ' . $theIssue->getFormattedIssueNo() . "\n"; } else { $output .= 'Can\'t find ' . $issue_no . ' so not updating that one.' . "\n"; } } } return $output; }
/** * Add a related issue * * @param TBGIssue $related_issue * * @return boolean */ public function addChildIssue(TBGIssue $related_issue) { if (!($row = B2DB::getTable('TBGIssueRelationsTable')->getIssueRelation($this->getID(), $related_issue->getID()))) { $res = B2DB::getTable('TBGIssueRelationsTable')->addChildIssue($this->getID(), $related_issue->getID()); $this->_child_issues = null; $related_issue->addLogEntry(TBGLogTable::LOG_ISSUE_DEPENDS, TBGContext::getI18n()->__('%issuetype% %issue_no% now depends on the solution of this %this_issuetype%', array('%this_issuetype%' => $related_issue->getIssueType()->getName(), '%issuetype%' => $this->getIssueType()->getName(), '%issue_no%' => $this->getFormattedIssueNo()))); $related_issue->addSystemComment(TBGContext::getI18n()->__('Dependancy added'), TBGContext::getI18n()->__('%issuetype% %issue_no% now depends on the solution of this %this_issuetype%', array('%this_issuetype%' => $related_issue->getIssueType()->getName(), '%issuetype%' => $this->getIssueType()->getName(), '%issue_no%' => $this->getFormattedIssueNo())), TBGContext::getUser()->getID()); $this->addLogEntry(TBGLogTable::LOG_ISSUE_DEPENDS, TBGContext::getI18n()->__('This %this_issuetype% now depends on the solution of %issuetype% %issue_no%', array('%this_issuetype%' => $this->getIssueType()->getName(), '%issuetype%' => $related_issue->getIssueType()->getName(), '%issue_no%' => $related_issue->getFormattedIssueNo()))); $comment = $this->addSystemComment(TBGContext::getI18n()->__('Dependancy added'), TBGContext::getI18n()->__('This %this_issuetype% now depends on the solution of %issuetype% %issue_no%', array('%this_issuetype%' => $this->getIssueType()->getName(), '%issuetype%' => $related_issue->getIssueType()->getName(), '%issue_no%' => $related_issue->getFormattedIssueNo())), TBGContext::getUser()->getID()); return $comment instanceof TBGComment ? $comment : true; } return false; }
protected function _performSearch() { list($this->_issues, $this->_total_number_of_issues) = TBGIssue::findIssues($this->getFilters(), $this->getIssuesPerPage(), $this->getOffset(), $this->getGroupby(), $this->getGrouporder(), $this->getSortFields()); }
public function componentBulkWorkflow() { $workflow_items = array(); $project = null; $issues = array(); $first = true; foreach ($this->issue_ids as $issue_id) { $issue = new TBGIssue($issue_id); $issues[$issue_id] = $issue; if ($first) { $workflow_items = $issue->getAvailableWorkflowTransitions(); $project = $issue->getProject(); $first = false; } else { $transitions = $issue->getAvailableWorkflowTransitions(); foreach ($workflow_items as $transition_id => $transition) { if (!array_key_exists($transition_id, $transitions)) { unset($workflow_items[$transition_id]); } } if ($issue->getProject()->getID() != $project->getID()) { $project = null; break; } } if (!count($workflow_items)) { break; } } $this->issues = $issues; $this->project = $project; $this->available_transitions = $workflow_items; }
</td> <td class="sc_spent_time<?php if (!$issue->hasSpentTime()) { ?> faded_out<?php } ?> "<?php if (!in_array('spent_time', $visible_columns)) { ?> style="display: none;"<?php } ?> > <?php echo !$issue->hasSpentTime() ? '-' : TBGIssue::getFormattedTime($issue->getSpentTime()); ?> </td> <td class="smaller sc_last_updated" title="<?php echo tbg_formatTime($issue->getLastUpdatedTime(), 21); ?> "<?php if (!in_array('last_updated', $visible_columns)) { ?> style="display: none;"<?php } ?> ><span style="display: none;"><?php echo $issue->getLastUpdatedTime(); ?> </span><?php
<div class="results_summary"> <div class="summary_header"><?php echo __('In the group above (on this page)'); ?> </div> <?php echo __('Total number of issues: %number', array('%number' => '<span class="issue_count">' . $current_count . '</span>')); ?> <br> <?php echo __('Total estimated effort: %details', array('%details' => '<span class="issue_estimated_time_summary">' . TBGIssue::getFormattedTime($current_estimated_time, false) . '</span>')); ?> <br> <?php echo __('Total current effort: %details', array('%details' => '<span class="issue_spent_time_summary">' . TBGIssue::getFormattedTime($current_spent_time, false) . '</span>')); ?> <br> </div>
static function userPainSort(TBGIssue $first_issue, TBGIssue $second_issue) { $first_issue_pain = $first_issue->getUserPain(); $second_issue_pain = $second_issue->getUserPain(); if ($first_issue_pain == $second_issue_pain) { return 0; } return $first_issue_pain < $second_issue_pain ? -1 : 1; }
public function componentReportIssue() { $introarticle = TBGArticlesTable::getTable()->getArticleByName(ucfirst(TBGContext::getCurrentProject()->getKey()) . ':ReportIssueIntro'); $this->introarticle = $introarticle instanceof TBGWikiArticle ? $introarticle : TBGArticlesTable::getTable()->getArticleByName('ReportIssueIntro'); $reporthelparticle = TBGArticlesTable::getTable()->getArticleByName(ucfirst(TBGContext::getCurrentProject()->getKey()) . ':ReportIssueHelp'); $this->reporthelparticle = $reporthelparticle instanceof TBGWikiArticle ? $reporthelparticle : TBGArticlesTable::getTable()->getArticleByName('ReportIssueHelp'); $this->uniqid = TBGContext::getRequest()->getParameter('uniqid', uniqid()); $this->_setupReportIssueProperties(); $dummyissue = new TBGIssue(); $dummyissue->setProject(TBGContext::getCurrentProject()); $this->canupload = TBGSettings::isUploadsEnabled() && $dummyissue->canAttachFiles(); }
public function runDoImportCSV(TBGRequest $request) { try { if ($request['csv_data'] == '') { throw new Exception($this->getI18n()->__('No data supplied to import')); } $csv = str_replace("\r\n", "\n", $request['csv_data']); $csv = html_entity_decode($csv); $headerrow = null; $data = array(); $errors = array(); // Parse CSV $handle = fopen("php://memory", 'r+'); fputs($handle, $csv); rewind($handle); $i = 0; while (($row = fgetcsv($handle, 1000)) !== false) { if (!$headerrow) { $headerrow = $row; } else { if (count($headerrow) == count($row)) { $data[] = array_combine($headerrow, $row); } else { $errors[] = $this->getI18n()->__('Row %row does not have the same number of elements as the header row', array('%row' => $i)); } } $i++; } fclose($handle); if (empty($data)) { throw new Exception($this->getI18n()->__('Insufficient data to import')); } // Verify required columns are present based on type $requiredcols = array(self::CSV_TYPE_CLIENTS => array(self::CSV_CLIENT_NAME), self::CSV_TYPE_PROJECTS => array(self::CSV_PROJECT_NAME), self::CSV_TYPE_ISSUES => array(self::CSV_ISSUE_TITLE, self::CSV_ISSUE_PROJECT, self::CSV_ISSUE_ISSUE_TYPE)); if (!isset($requiredcols[$request['type']])) { throw new Exception('Sorry, this type is unimplemented'); } foreach ($requiredcols[$request['type']] as $col) { if (!in_array($col, $headerrow)) { $errors[] = $this->getI18n()->__('Required column \'%col\' not found in header row', array('%col' => $col)); } } // Check if rows are long enough and fields are not empty for ($i = 0; $i != count($data); $i++) { $activerow = $data[$i]; // Check if fields are empty foreach ($activerow as $col => $val) { if (strlen($val) == 0) { $errors[] = $this->getI18n()->__('Row %row column %col has no value', array('%col' => $col, '%row' => $i + 1)); } } } if (count($errors) == 0) { // Check if fields are valid switch ($request['type']) { case self::CSV_TYPE_PROJECTS: for ($i = 0; $i != count($data); $i++) { $activerow = $data[$i]; // Check if project exists $key = str_replace(' ', '', $activerow[self::CSV_PROJECT_NAME]); $key = mb_strtolower($key); $tmp = TBGProject::getByKey($key); if ($tmp !== null) { $errors[] = $this->getI18n()->__('Row %row: A project with this name already exists', array('%row' => $i + 1)); } // First off are booleans $boolitems = array(self::CSV_PROJECT_SCRUM, self::CSV_PROJECT_ALLOW_REPORTING, self::CSV_PROJECT_AUTOASSIGN, self::CSV_PROJECT_FREELANCE, self::CSV_PROJECT_EN_BUILDS, self::CSV_PROJECT_EN_COMPS, self::CSV_PROJECT_EN_EDITIONS, self::CSV_PROJECT_SHOW_SUMMARY); foreach ($boolitems as $boolitem) { if (array_key_exists($boolitem, $activerow) && isset($activerow[$boolitem]) && $activerow[$boolitem] != 1 && $activerow[$boolitem] != 0) { $errors[] = $this->getI18n()->__('Row %row column %col: invalid value (must be 1/0)', array('%col' => $boolitem, '%row' => $i + 1)); } } // Now identifiables $identifiableitems = array(array(self::CSV_PROJECT_QA, self::CSV_PROJECT_QA_TYPE), array(self::CSV_PROJECT_LEAD, self::CSV_PROJECT_LEAD_TYPE), array(self::CSV_PROJECT_OWNER, self::CSV_PROJECT_OWNER_TYPE)); foreach ($identifiableitems as $identifiableitem) { if (!array_key_exists($identifiableitem[1], $activerow) && array_key_exists($identifiableitem[0], $activerow) || array_key_exists($identifiableitem[1], $activerow) && !array_key_exists($identifiableitem[0], $activerow)) { $errors[] = $this->getI18n()->__('Row %row: Both the type and item ID must be supplied for owner/lead/qa fields', array('%row' => $i + 1)); continue; } if (array_key_exists($identifiableitem[1], $activerow) && isset($activerow[$identifiableitem[1]]) !== null && $activerow[$identifiableitem[1]] != self::CSV_IDENTIFIER_TYPE_USER && $activerow[$identifiableitem[1]] != self::CSV_IDENTIFIER_TYPE_TEAM) { $errors[] = $this->getI18n()->__('Row %row column %col: invalid value (must be 1 for a user or 2 for a team)', array('%col' => $identifiableitem[1], '%row' => $i + 1)); } if (array_key_exists($identifiableitem[0], $activerow) && isset($activerow[$identifiableitem[0]]) && !is_numeric($activerow[$identifiableitem[0]])) { $errors[] = $this->getI18n()->__('Row %row column %col: invalid value (must be a number)', array('%col' => $identifiableitem[0], '%row' => $i + 1)); } elseif (array_key_exists($identifiableitem[0], $activerow) && isset($activerow[$identifiableitem[0]]) && is_numeric($activerow[$identifiableitem[0]])) { // check if they exist switch ($activerow[$identifiableitem[1]]) { case self::CSV_IDENTIFIER_TYPE_USER: try { TBGContext::factory()->TBGUser($activerow[$identifiableitem[0]]); } catch (Exception $e) { $errors[] = $this->getI18n()->__('Row %row column %col: user does not exist', array('%col' => $identifiableitem[0], '%row' => $i + 1)); } break; case self::CSV_IDENTIFIER_TYPE_TEAM: try { TBGContext::factory()->TBGTeam($activerow[$identifiableitem[0]]); } catch (Exception $e) { $errors[] = $this->getI18n()->__('Row %row column %col: team does not exist', array('%col' => $identifiableitem[0], '%row' => $i + 1)); } break; } } } // Now check client exists if (array_key_exists(self::CSV_PROJECT_CLIENT, $activerow) && isset($activerow[self::CSV_PROJECT_CLIENT])) { if (!is_numeric($activerow[self::CSV_PROJECT_CLIENT])) { $errors[] = $this->getI18n()->__('Row %row column %col: invalid value (must be a number)', array('%col' => self::CSV_PROJECT_CLIENT, '%row' => $i + 1)); } else { try { TBGContext::factory()->TBGClient($activerow[self::CSV_PROJECT_CLIENT]); } catch (Exception $e) { $errors[] = $this->getI18n()->__('Row %row column %col: client does not exist', array('%col' => self::CSV_PROJECT_CLIENT, '%row' => $i + 1)); } } } // Now check if workflow exists if (array_key_exists(self::CSV_PROJECT_WORKFLOW_ID, $activerow) && isset($activerow[self::CSV_PROJECT_WORKFLOW_ID])) { if (!is_numeric($activerow[self::CSV_PROJECT_WORKFLOW_ID])) { $errors[] = $this->getI18n()->__('Row %row column %col: invalid value (must be a number)', array('%col' => self::CSV_PROJECT_WORKFLOW_ID, '%row' => $i + 1)); } else { try { TBGContext::factory()->TBGWorkflowScheme($activerow[self::CSV_PROJECT_WORKFLOW_ID]); } catch (Exception $e) { $errors[] = $this->getI18n()->__('Row %row column %col: workflow scheme does not exist', array('%col' => self::CSV_PROJECT_WORKFLOW_ID, '%row' => $i + 1)); } } } // Now check if issuetype scheme if (array_key_exists(self::CSV_PROJECT_ISSUETYPE_SCHEME, $activerow) && isset($activerow[self::CSV_PROJECT_ISSUETYPE_SCHEME])) { if (!is_numeric($activerow[self::CSV_PROJECT_ISSUETYPE_SCHEME])) { $errors[] = $this->getI18n()->__('Row %row column %col: invalid value (must be a number)', array('%col' => self::CSV_PROJECT_ISSUETYPE_SCHEME, '%row' => $i + 1)); } else { try { TBGContext::factory()->TBGIssuetypeScheme($activerow[self::CSV_PROJECT_ISSUETYPE_SCHEME]); } catch (Exception $e) { $errors[] = $this->getI18n()->__('Row %row column %col: issuetype scheme does not exist', array('%col' => self::CSV_PROJECT_ISSUETYPE_SCHEME, '%row' => $i + 1)); } } } // Finally check if the summary type is valid. At this point, your error list has probably become so big it has eaten up all your available RAM... if (array_key_exists(self::CSV_PROJECT_SUMMARY_TYPE, $activerow) && isset($activerow[self::CSV_PROJECT_SUMMARY_TYPE])) { if ($activerow[self::CSV_PROJECT_SUMMARY_TYPE] != 'issuetypes' && $activerow[self::CSV_PROJECT_SHOW_SUMMARY] != 'milestones') { $errors[] = $this->getI18n()->__('Row %row column %col: invalid value (must be \'issuetypes\' or \'milestones\')', array('%col' => self::CSV_PROJECT_SUMMARY_TYPE, '%row' => $i + 1)); } } } break; case self::CSV_TYPE_ISSUES: for ($i = 0; $i != count($data); $i++) { $activerow = $data[$i]; // Check if project exists try { $prjtmp = TBGContext::factory()->TBGProject($activerow[self::CSV_ISSUE_PROJECT]); } catch (Exception $e) { $errors[] = $this->getI18n()->__('Row %row column %col: Project does not exist', array('%col' => self::CSV_ISSUE_PROJECT, '%row' => $i + 1)); break; } // First off are booleans $boolitems = array(self::CSV_ISSUE_STATE, self::CSV_ISSUE_BLOCKING); foreach ($boolitems as $boolitem) { if (array_key_exists($boolitem, $activerow) && isset($activerow[$boolitem]) && $activerow[$boolitem] != 1 && $activerow[$boolitem] != 0) { $errors[] = $this->getI18n()->__('Row %row column %col: invalid value (must be 1/0)', array('%col' => $boolitem, '%row' => $i + 1)); } } // Now numerics $numericitems = array(self::CSV_ISSUE_VOTES, self::CSV_ISSUE_PERCENTAGE, self::CSV_ISSUE_ISSUENO); foreach ($numericitems as $numericitem) { if (array_key_exists($numericitem, $activerow) && isset($activerow[$numericitem]) && !is_numeric($activerow[$numericitem])) { $errors[] = $this->getI18n()->__('Row %row column %col: invalid value (must be a number)', array('%col' => $numericitem, '%row' => $i + 1)); } } // Percentage must be 0-100 if (array_key_exists(self::CSV_ISSUE_PERCENTAGE, $activerow) && isset($activerow[self::CSV_ISSUE_PERCENTAGE]) && ($activerow[self::CSV_ISSUE_PERCENTAGE] < 0 || $activerow[self::CSV_ISSUE_PERCENTAGE] > 100)) { $errors[] = $this->getI18n()->__('Row %row column %col: Percentage must be from 0 to 100 inclusive', array('%col' => self::CSV_ISSUE_PERCENTAGE, '%row' => $i + 1)); } // Now identifiables $identifiableitems = array(array(self::CSV_ISSUE_OWNER, self::CSV_ISSUE_OWNER_TYPE), array(self::CSV_ISSUE_ASSIGNED, self::CSV_ISSUE_ASSIGNED_TYPE)); foreach ($identifiableitems as $identifiableitem) { if (!array_key_exists($identifiableitem[1], $activerow) && array_key_exists($identifiableitem[0], $activerow) || array_key_exists($identifiableitem[1], $activerow) && !array_key_exists($identifiableitem[0], $activerow)) { $errors[] = $this->getI18n()->__('Row %row: Both the type and item ID must be supplied for owner/lead/qa fields', array('%row' => $i + 1)); continue; } if (array_key_exists($identifiableitem[1], $activerow) && isset($activerow[$identifiableitem[1]]) && $activerow[$identifiableitem[1]] != self::CSV_IDENTIFIER_TYPE_USER && $activerow[$identifiableitem[1]] != self::CSV_IDENTIFIER_TYPE_TEAM) { $errors[] = $this->getI18n()->__('Row %row column %col: invalid value (must be 1 for a user or 2 for a team)', array('%col' => $identifiableitem[1], '%row' => $i + 1)); } if (array_key_exists($identifiableitem[0], $activerow) && isset($activerow[$identifiableitem[0]]) && !is_numeric($activerow[$identifiableitem[0]])) { $errors[] = $this->getI18n()->__('Row %row column %col: invalid value (must be a number)', array('%col' => $identifiableitem[0], '%row' => $i + 1)); } elseif (array_key_exists($identifiableitem[0], $activerow) && isset($activerow[$identifiableitem[0]]) && is_numeric($activerow[$identifiableitem[0]])) { // check if they exist switch ($activerow[$identifiableitem[1]]) { case self::CSV_IDENTIFIER_TYPE_USER: try { TBGContext::factory()->TBGUser($activerow[$identifiableitem[0]]); } catch (Exception $e) { $errors[] = $this->getI18n()->__('Row %row column %col: user does not exist', array('%col' => $identifiableitem[0], '%row' => $i + 1)); } break; case self::CSV_IDENTIFIER_TYPE_TEAM: try { TBGContext::factory()->TBGTeam($activerow[$identifiableitem[0]]); } catch (Exception $e) { $errors[] = $this->getI18n()->__('Row %row column %col: team does not exist', array('%col' => $identifiableitem[0], '%row' => $i + 1)); } break; } } } // Now timestamps if (array_key_exists(self::CSV_ISSUE_POSTED, $activerow) && isset($activerow[self::CSV_ISSUE_POSTED]) && (string) (int) $activerow[self::CSV_ISSUE_POSTED] !== $activerow[self::CSV_ISSUE_POSTED] && $activerow[self::CSV_ISSUE_POSTED] >= PHP_INT_MAX && $activerow[self::CSV_ISSUE_POSTED] <= ~PHP_INT_MAX) { $errors[] = $this->getI18n()->__('Row %row column %col: invalid value (must be a Unix timestamp)', array('%col' => self::CSV_ISSUE_POSTED, '%row' => $i + 1)); } // Now check user exists for postedby if (array_key_exists(self::CSV_ISSUE_POSTED_BY, $activerow) && isset($activerow[self::CSV_ISSUE_POSTED_BY])) { if (!is_numeric($activerow[self::CSV_ISSUE_POSTED_BY])) { $errors[] = $this->getI18n()->__('Row %row column %col: invalid value (must be a number)', array('%col' => self::CSV_ISSUE_POSTED_BY, '%row' => $i + 1)); } else { try { TBGContext::factory()->TBGUser($activerow[self::CSV_ISSUE_POSTED_BY]); } catch (Exception $e) { $errors[] = $this->getI18n()->__('Row %row column %col: user does not exist', array('%col' => self::CSV_ISSUE_POSTED_BY, '%row' => $i + 1)); } } } // Now check milestone exists and is valid if (array_key_exists(self::CSV_ISSUE_MILESTONE, $activerow) && isset($activerow[self::CSV_ISSUE_MILESTONE])) { if (!is_numeric($activerow[self::CSV_ISSUE_MILESTONE])) { $errors[] = $this->getI18n()->__('Row %row column %col: invalid value (must be a number)', array('%col' => self::CSV_ISSUE_MILESTONE, '%row' => $i + 1)); } else { try { $milestonetmp = TBGContext::factory()->TBGMilestone($activerow[self::CSV_ISSUE_MILESTONE]); if ($milestonetmp->getProject()->getID() != $activerow[self::CSV_ISSUE_PROJECT]) { $errors[] = $this->getI18n()->__('Row %row column %col: milestone does not apply to the specified project', array('%col' => self::CSV_ISSUE_MILESTONE, '%row' => $i + 1)); } } catch (Exception $e) { $errors[] = $this->getI18n()->__('Row %row column %col: milestone does not exist', array('%col' => self::CSV_ISSUE_MILESTONE, '%row' => $i + 1)); } } } // status if (array_key_exists(self::CSV_ISSUE_STATUS, $activerow) && isset($activerow[self::CSV_ISSUE_STATUS])) { if (!is_numeric($activerow[self::CSV_ISSUE_STATUS])) { $errors[] = $this->getI18n()->__('Row %row column %col: invalid value (must be a number)', array('%col' => self::CSV_ISSUE_STATUS, '%row' => $i + 1)); } else { try { TBGContext::factory()->TBGStatus($activerow[self::CSV_ISSUE_STATUS]); } catch (Exception $e) { $errors[] = $this->getI18n()->__('Row %row column %col: status does not exist', array('%col' => self::CSV_ISSUE_STATUS, '%row' => $i + 1)); } } } // resolution if (array_key_exists(self::CSV_ISSUE_RESOLUTION, $activerow) && isset($activerow[self::CSV_ISSUE_RESOLUTION])) { if (!is_numeric($activerow[self::CSV_ISSUE_RESOLUTION])) { $errors[] = $this->getI18n()->__('Row %row column %col: invalid value (must be a number)', array('%col' => self::CSV_ISSUE_RESOLUTION, '%row' => $i + 1)); } else { try { TBGContext::factory()->TBGResolution($activerow[self::CSV_ISSUE_RESOLUTION]); } catch (Exception $e) { $errors[] = $this->getI18n()->__('Row %row column %col: resolution does not exist', array('%col' => self::CSV_ISSUE_RESOLUTION, '%row' => $i + 1)); } } } // priority if (array_key_exists(self::CSV_ISSUE_PRIORITY, $activerow) && isset($activerow[self::CSV_ISSUE_PRIORITY])) { if (!is_numeric($activerow[self::CSV_ISSUE_PRIORITY])) { $errors[] = $this->getI18n()->__('Row %row column %col: invalid value (must be a number)', array('%col' => self::CSV_ISSUE_PRIORITY, '%row' => $i + 1)); } else { try { TBGContext::factory()->TBGPriority($activerow[self::CSV_ISSUE_PRIORITY]); } catch (Exception $e) { $errors[] = $this->getI18n()->__('Row %row column %col: priority does not exist', array('%col' => self::CSV_ISSUE_PRIORITY, '%row' => $i + 1)); } } } // category if (array_key_exists(self::CSV_ISSUE_CATEGORY, $activerow) && isset($activerow[self::CSV_ISSUE_CATEGORY])) { if (!is_numeric($activerow[self::CSV_ISSUE_CATEGORY])) { $errors[] = $this->getI18n()->__('Row %row column %col: invalid value (must be a number)', array('%col' => self::CSV_ISSUE_CATEGORY, '%row' => $i + 1)); } else { try { TBGContext::factory()->TBGCategory($activerow[self::CSV_ISSUE_CATEGORY]); } catch (Exception $e) { $errors[] = $this->getI18n()->__('Row %row column %col: category does not exist', array('%col' => self::CSV_ISSUE_CATEGORY, '%row' => $i + 1)); } } } // severity if (array_key_exists(self::CSV_ISSUE_SEVERITY, $activerow) && isset($activerow[self::CSV_ISSUE_SEVERITY])) { if (!is_numeric($activerow[self::CSV_ISSUE_SEVERITY])) { $errors[] = $this->getI18n()->__('Row %row column %col: invalid value (must be a number)', array('%col' => self::CSV_ISSUE_SEVERITY, '%row' => $i + 1)); } else { try { TBGContext::factory()->TBGSeverity($activerow[self::CSV_ISSUE_SEVERITY]); } catch (Exception $e) { $errors[] = $this->getI18n()->__('Row %row column %col: severity does not exist', array('%col' => self::CSV_ISSUE_SEVERITY, '%row' => $i + 1)); } } } // reproducability if (array_key_exists(self::CSV_ISSUE_REPRODUCIBILITY, $activerow) && isset($activerow[self::CSV_ISSUE_REPRODUCIBILITY])) { if (!is_numeric($activerow[self::CSV_ISSUE_REPRODUCIBILITY])) { $errors[] = $this->getI18n()->__('Row %row column %col: invalid value (must be a number)', array('%col' => self::CSV_ISSUE_REPRODUCIBILITY, '%row' => $i + 1)); } else { try { TBGContext::factory()->TBGReproducability($activerow[self::CSV_ISSUE_REPRODUCIBILITY]); } catch (Exception $e) { $errors[] = $this->getI18n()->__('Row %row column %col: reproducability does not exist', array('%col' => self::CSV_ISSUE_REPRODUCIBILITY, '%row' => $i + 1)); } } } // type if (array_key_exists(self::CSV_ISSUE_ISSUE_TYPE, $activerow) && isset($activerow[self::CSV_ISSUE_ISSUE_TYPE])) { if (!is_numeric($activerow[self::CSV_ISSUE_ISSUE_TYPE])) { $errors[] = $this->getI18n()->__('Row %row column %col: invalid value (must be a number)', array('%col' => self::CSV_ISSUE_ISSUE_TYPE, '%row' => $i + 1)); } else { try { $typetmp = TBGContext::factory()->TBGIssuetype($activerow[self::CSV_ISSUE_ISSUE_TYPE]); if (!$prjtmp->getIssuetypeScheme()->isSchemeAssociatedWithIssuetype($typetmp)) { $errors[] = $this->getI18n()->__('Row %row column %col: this project does not support issues of this type (%type)', array('%type' => $typetmp->getName(), '%col' => self::CSV_ISSUE_ISSUE_TYPE, '%row' => $i + 1)); } } catch (Exception $e) { $errors[] = $this->getI18n()->__('Row %row column %col: issue type does not exist', array('%col' => self::CSV_ISSUE_ISSUE_TYPE, '%row' => $i + 1)); } } } } break; } } // Handle errors if (count($errors) != 0) { $errordiv = '<ul>'; foreach ($errors as $error) { $errordiv .= '<li>' . $error . '</li>'; } $errordiv .= '</ul>'; $this->getResponse()->setHttpStatus(400); return $this->renderJSON(array('errordetail' => $errordiv, 'error' => $this->getI18n()->__('Errors occured while importing, see the error list in the import screen for further details'))); } } catch (Exception $e) { $this->getResponse()->setHttpStatus(400); return $this->renderJSON(array('errordetail' => $e->getMessage(), 'error' => $e->getMessage())); } if ($request['csv_dry_run']) { return $this->renderJSON(array('message' => $this->getI18n()->__('Dry-run successful, you can now uncheck the dry-run box and import your data.'))); } else { switch ($request['type']) { case self::CSV_TYPE_CLIENTS: for ($i = 0; $i != count($data); $i++) { try { $activerow = $data[$i]; $client = new TBGClient(); $client->setName($activerow[self::CSV_CLIENT_NAME]); if (isset($activerow[self::CSV_CLIENT_EMAIL])) { $client->setEmail($activerow[self::CSV_CLIENT_EMAIL]); } if (isset($activerow[self::CSV_CLIENT_WEBSITE])) { $client->setWebsite($activerow[self::CSV_CLIENT_WEBSITE]); } if (isset($activerow[self::CSV_CLIENT_FAX])) { $client->setFax($activerow[self::CSV_CLIENT_FAX]); } if (isset($activerow[self::CSV_CLIENT_TELEPHONE])) { $client->setTelephone($activerow[self::CSV_CLIENT_TELEPHONE]); } $client->save(); } catch (Exception $e) { $errors[] = $this->getI18n()->__('Row %row failed: %err', array('%row' => $i + 1, '%err' => $e->getMessage())); } } break; case self::CSV_TYPE_PROJECTS: for ($i = 0; $i != count($data); $i++) { try { $activerow = $data[$i]; $project = new TBGProject(); $project->setName($activerow[self::CSV_PROJECT_NAME]); $project->save(); if (isset($activerow[self::CSV_PROJECT_PREFIX])) { $project->setPrefix($activerow[self::CSV_PROJECT_PREFIX]); $project->setUsePrefix(true); } if (isset($activerow[self::CSV_PROJECT_SCRUM])) { if ($activerow[self::CSV_PROJECT_SCRUM] == '1') { $project->setUsesScrum(true); } } if (isset($activerow[self::CSV_PROJECT_OWNER]) && isset($activerow[self::CSV_PROJECT_OWNER_TYPE])) { switch ($activerow[self::CSV_PROJECT_OWNER_TYPE]) { case self::CSV_IDENTIFIER_TYPE_USER: $user = new TBGUser($activerow[self::CSV_PROJECT_OWNER]); $project->setOwner($user); break; case self::CSV_IDENTIFIER_TYPE_TEAM: $team = new TBGTeam($activerow[self::CSV_PROJECT_OWNER]); $project->setOwner($team); break; } } if (isset($activerow[self::CSV_PROJECT_LEAD]) && isset($activerow[self::CSV_PROJECT_LEAD_TYPE])) { switch ($activerow[self::CSV_PROJECT_LEAD_TYPE]) { case self::CSV_IDENTIFIER_TYPE_USER: $user = new TBGUser($activerow[self::CSV_PROJECT_LEAD]); $project->setLeader($user); break; case self::CSV_IDENTIFIER_TYPE_TEAM: $team = new TBGTeam($activerow[self::CSV_PROJECT_LEAD]); $project->setLeader($team); break; } } if (isset($activerow[self::CSV_PROJECT_QA]) && isset($activerow[self::CSV_PROJECT_QA_TYPE])) { switch ($activerow[self::CSV_PROJECT_QA_TYPE]) { case self::CSV_IDENTIFIER_TYPE_USER: $user = new TBGUser($activerow[self::CSV_PROJECT_QA]); $project->setQaResponsible($user); break; case self::CSV_IDENTIFIER_TYPE_TEAM: $team = new TBGTeam($activerow[self::CSV_PROJECT_QA]); $project->setQaResponsible($team); break; } } if (isset($activerow[self::CSV_PROJECT_DESCR])) { $project->setDescription($activerow[self::CSV_PROJECT_DESCR]); } if (isset($activerow[self::CSV_PROJECT_DOC_URL])) { $project->setDocumentationUrl($activerow[self::CSV_PROJECT_DOC_URL]); } if (isset($activerow[self::CSV_PROJECT_WIKI_URL])) { $project->setWikiUrl($activerow[self::CSV_PROJECT_WIKI_URL]); } if (isset($activerow[self::CSV_PROJECT_FREELANCE])) { if ($activerow[self::CSV_PROJECT_FREELANCE] == '1') { $project->setChangeIssuesWithoutWorkingOnThem(true); } } if (isset($activerow[self::CSV_PROJECT_EN_BUILDS])) { if ($activerow[self::CSV_PROJECT_EN_BUILDS] == '1') { $project->setBuildsEnabled(true); } } if (isset($activerow[self::CSV_PROJECT_EN_COMPS])) { if ($activerow[self::CSV_PROJECT_EN_COMPS] == '1') { $project->setComponentsEnabled(true); } } if (isset($activerow[self::CSV_PROJECT_EN_EDITIONS])) { if ($activerow[self::CSV_PROJECT_EN_EDITIONS] == '1') { $project->setEditionsEnabled(true); } } if (isset($activerow[self::CSV_PROJECT_CLIENT])) { $project->setClient(TBGContext::factory()->TBGClient($activerow[self::CSV_PROJECT_CLIENT])); } if (isset($activerow[self::CSV_PROJECT_SHOW_SUMMARY])) { if ($activerow[self::CSV_PROJECT_SHOW_SUMMARY] == '1') { $project->setFrontpageSummaryVisibility(true); } } if (isset($activerow[self::CSV_PROJECT_SUMMARY_TYPE])) { $project->setFrontpageSummaryType($activerow[self::CSV_PROJECT_SUMMARY_TYPE]); } if (isset($activerow[self::CSV_PROJECT_ALLOW_REPORTING])) { $project->setLocked($activerow[self::CSV_PROJECT_ALLOW_REPORTING]); } if (isset($activerow[self::CSV_PROJECT_AUTOASSIGN])) { $project->setAutoassign($activerow[self::CSV_PROJECT_AUTOASSIGN]); } if (isset($activerow[self::CSV_PROJECT_ISSUETYPE_SCHEME])) { $project->setIssuetypeScheme(TBGContext::factory()->TBGIssuetypeScheme($activerow[self::CSV_PROJECT_ISSUETYPE_SCHEME])); } if (isset($activerow[self::CSV_PROJECT_WORKFLOW_ID])) { } $project->setWorkflowScheme(TBGContext::factory()->TBGWorkflowScheme($activerow[self::CSV_PROJECT_WORKFLOW_ID])); $project->save(); } catch (Exception $e) { $errors[] = $this->getI18n()->__('Row %row failed: %err', array('%row' => $i + 1, '%err' => $e->getMessage())); } } break; case self::CSV_TYPE_ISSUES: for ($i = 0; $i != count($data); $i++) { try { $activerow = $data[$i]; $issue = new TBGIssue(); $issue->setTitle($activerow[self::CSV_ISSUE_TITLE]); $issue->setProject($activerow[self::CSV_ISSUE_PROJECT]); $issue->setIssuetype($activerow[self::CSV_ISSUE_ISSUE_TYPE]); $issue->save(); if (isset($activerow[self::CSV_ISSUE_DESCR])) { $issue->setDescription($activerow[self::CSV_ISSUE_DESCR]); } if (isset($activerow[self::CSV_ISSUE_REPRO])) { $issue->setReproductionSteps($activerow[self::CSV_ISSUE_REPRO]); } if (isset($activerow[self::CSV_ISSUE_STATE])) { $issue->setState($activerow[self::CSV_ISSUE_STATE]); } if (isset($activerow[self::CSV_ISSUE_STATUS])) { $issue->setStatus($activerow[self::CSV_ISSUE_STATUS]); } if (isset($activerow[self::CSV_ISSUE_POSTED_BY])) { $issue->setPostedBy(TBGContext::factory()->TBGUser($activerow[self::CSV_ISSUE_POSTED_BY])); } if (isset($activerow[self::CSV_ISSUE_OWNER]) && isset($activerow[self::CSV_ISSUE_OWNER_TYPE])) { switch ($activerow[self::CSV_ISSUE_OWNER_TYPE]) { case self::CSV_IDENTIFIER_TYPE_USER: $user = new TBGUser($activerow[self::CSV_ISSUE_OWNER]); $issue->setOwner($user); break; case self::CSV_IDENTIFIER_TYPE_TEAM: $team = new TBGTeam($activerow[self::CSV_ISSUE_OWNER]); $issue->setOwner($team); break; } } if (isset($activerow[self::CSV_ISSUE_ASSIGNED]) && isset($activerow[self::CSV_ISSUE_ASSIGNED_TYPE])) { switch ($activerow[self::CSV_ISSUE_ASSIGNED_TYPE]) { case self::CSV_IDENTIFIER_TYPE_USER: $user = new TBGUser($activerow[self::CSV_ISSUE_ASSIGNED]); $issue->setAssignee($user); break; case self::CSV_IDENTIFIER_TYPE_TEAM: $team = new TBGTeam($activerow[self::CSV_ISSUE_ASSIGNED]); $issue->setAssignee($team); break; } } if (isset($activerow[self::CSV_ISSUE_RESOLUTION])) { $issue->setResolution($activerow[self::CSV_ISSUE_RESOLUTION]); } if (isset($activerow[self::CSV_ISSUE_PRIORITY])) { $issue->setPriority($activerow[self::CSV_ISSUE_PRIORITY]); } if (isset($activerow[self::CSV_ISSUE_CATEGORY])) { $issue->setCategory($activerow[self::CSV_ISSUE_CATEGORY]); } if (isset($activerow[self::CSV_ISSUE_BLOCKING])) { $issue->setBlocking($activerow[self::CSV_ISSUE_BLOCKING]); } if (isset($activerow[self::CSV_ISSUE_SEVERITY])) { $issue->setSeverity($activerow[self::CSV_ISSUE_SEVERITY]); } if (isset($activerow[self::CSV_ISSUE_REPRODUCIBILITY])) { $issue->setReproducability($activerow[self::CSV_ISSUE_REPRODUCIBILITY]); } if (isset($activerow[self::CSV_ISSUE_VOTES])) { $issue->setVotes($activerow[self::CSV_ISSUE_VOTES]); } if (isset($activerow[self::CSV_ISSUE_PERCENTAGE])) { $issue->setPercentCompleted($activerow[self::CSV_ISSUE_PERCENTAGE]); } if (isset($activerow[self::CSV_ISSUE_ISSUENO])) { $issue->setIssueNo((int) $activerow[self::CSV_ISSUE_ISSUENO]); } if (isset($activerow[self::CSV_ISSUE_MILESTONE])) { $issue->setMilestone($activerow[self::CSV_ISSUE_MILESTONE]); } if (isset($activerow[self::CSV_ISSUE_POSTED])) { $issue->setPosted((int) $activerow[self::CSV_ISSUE_POSTED]); } $issue->save(); } catch (Exception $e) { $errors[] = $this->getI18n()->__('Row %row failed: %err', array('%row' => $i + 1, '%err' => $e->getMessage())); } } break; } // Handle errors if (count($errors) != 0) { $errordiv = '<ul>'; foreach ($errors as $error) { $errordiv .= '<li>' . $error . '</li>'; } $errordiv .= '</ul>'; $this->getResponse()->setHttpStatus(400); return $this->renderJSON(array('errordetail' => $errordiv, 'error' => $this->getI18n()->__('Errors occured while importing, see the error list in the import screen for further details'))); } else { return $this->renderJSON(array('message' => $this->getI18n()->__('Successfully imported %num rows!', array('%num' => count($data))))); } } }
public function moveIssueToMatchingWorkflowStep(TBGIssue $issue) { $change_step = false; if ($issue->isStatusChanged() || $issue->isResolutionChanged()) { $change_step = true; } if ($change_step) { foreach ($this->getSteps() as $step) { if ($step->hasLinkedStatus() && $issue->getStatus() instanceof TBGStatus && $step->getLinkedStatusID() == $issue->getStatus()->getID()) { $step->applyToIssue($issue); return true; } } foreach ($this->getSteps() as $step) { if (!$step->hasLinkedStatus()) { foreach ($step->getIncomingTransitions() as $transition) { if ($transition->hasPostValidationRule(TBGWorkflowTransitionValidationRule::RULE_STATUS_VALID)) { $rule = $transition->getPostValidationRule(TBGWorkflowTransitionValidationRule::RULE_STATUS_VALID); if ($rule->isValid($issue)) { $step->applyToIssue($issue); return true; } } } } } } }
public function runUpdateIssueDetails(TBGRequest $request) { $this->forward403if(TBGContext::getCurrentProject()->isArchived()); $this->error = false; try { $i18n = TBGContext::getI18n(); $issue = TBGIssue::getIssueFromLink($request['issue_no']); if ($issue->getProject()->getID() != $this->selected_project->getID()) { throw new Exception($i18n->__('This issue is not valid for this project')); } if (!$issue instanceof TBGIssue) { die; } $workflow_transition = null; if ($passed_transition = $request['workflow_transition']) { //echo "looking for transition "; $key = str_replace(' ', '', mb_strtolower($passed_transition)); //echo $key . "\n"; foreach ($issue->getAvailableWorkflowTransitions() as $transition) { //echo str_replace(' ', '', mb_strtolower($transition->getName())) . "?"; if (mb_strpos(str_replace(' ', '', mb_strtolower($transition->getName())), $key) !== false) { $workflow_transition = $transition; //echo "found transition " . $transition->getID(); break; } //echo "no"; } if (!$workflow_transition instanceof TBGWorkflowTransition) { throw new Exception("This transition ({$key}) is not valid"); } } $fields = $request->getRawParameter('fields', array()); $return_values = array(); if ($workflow_transition instanceof TBGWorkflowTransition) { foreach ($fields as $field_key => $field_value) { $classname = "TBG" . ucfirst($field_key); $method = "set" . ucfirst($field_key); $choices = $classname::getAll(); $found = false; foreach ($choices as $choice_key => $choice) { if (mb_strpos(str_replace(' ', '', mb_strtolower($choice->getName())), str_replace(' ', '', mb_strtolower($field_value))) !== false) { $request->setParameter($field_key . '_id', $choice->getId()); break; } } } $request->setParameter('comment_body', $request['message']); $return_values['applied_transition'] = $workflow_transition->getName(); if ($workflow_transition->validateFromRequest($request)) { $retval = $workflow_transition->transitionIssueToOutgoingStepFromRequest($issue, $request); $return_values['transition_ok'] = $retval === false ? false : true; } else { $return_values['transition_ok'] = false; $return_values['message'] = "Please pass all information required for this transition"; } } elseif ($issue->isUpdateable()) { foreach ($fields as $field_key => $field_value) { try { if (in_array($field_key, array_merge(array('title', 'state'), TBGDatatype::getAvailableFields(true)))) { switch ($field_key) { case 'state': $issue->setState($field_value == 'open' ? TBGIssue::STATE_OPEN : TBGIssue::STATE_CLOSED); break; case 'title': if ($field_value != '') { $issue->setTitle($field_value); } else { throw new Exception($i18n->__('Invalid title')); } break; case 'description': case 'reproduction_steps': $method = "set" . ucfirst($field_key); $issue->{$method}($field_value); break; case 'status': case 'resolution': case 'reproducability': case 'priority': case 'severity': case 'category': $classname = "TBG" . ucfirst($field_key); $method = "set" . ucfirst($field_key); $choices = $classname::getAll(); $found = false; foreach ($choices as $choice_key => $choice) { if (str_replace(' ', '', mb_strtolower($choice->getName())) == str_replace(' ', '', mb_strtolower($field_value))) { $issue->{$method}($choice); $found = true; } } if (!$found) { throw new Exception('Could not find this value'); } break; case 'percent_complete': $issue->setPercentCompleted($field_value); break; case 'owner': case 'assignee': $set_method = "set" . ucfirst($field_key); $unset_method = "un{$set_method}"; switch (mb_strtolower($field_value)) { case 'me': $issue->{$set_method}(TBGContext::getUser()); break; case 'none': $issue->{$unset_method}(); break; default: try { $user = TBGUser::findUser(mb_strtolower($field_value)); if ($user instanceof TBGUser) { $issue->{$set_method}($user); } } catch (Exception $e) { throw new Exception('No such user found'); } break; } break; case 'estimated_time': case 'spent_time': $set_method = "set" . ucfirst(str_replace('_', '', $field_key)); $issue->{$set_method}($field_value); break; case 'milestone': $found = false; foreach ($this->selected_project->getMilestones() as $milestone) { if (str_replace(' ', '', mb_strtolower($milestone->getName())) == str_replace(' ', '', mb_strtolower($field_value))) { $issue->setMilestone($milestone->getID()); $found = true; } } if (!$found) { throw new Exception('Could not find this milestone'); } break; default: throw new Exception($i18n->__('Invalid field')); } } $return_values[$field_key] = array('success' => true); } catch (Exception $e) { $return_values[$field_key] = array('success' => false, 'error' => $e->getMessage()); } } } if (!$workflow_transition instanceof TBGWorkflowTransition) { $issue->getWorkflow()->moveIssueToMatchingWorkflowStep($issue); } if (!array_key_exists('transition_ok', $return_values) || $return_values['transition_ok']) { $comment = new TBGComment(); $comment->setTitle(''); $comment->setContent($request->getParameter('message', null, false)); $comment->setPostedBy(TBGContext::getUser()->getID()); $comment->setTargetID($issue->getID()); $comment->setTargetType(TBGComment::TYPE_ISSUE); $comment->setModuleName('core'); $comment->setIsPublic(true); $comment->setSystemComment(false); $comment->save(); $issue->setSaveComment($comment); $issue->save(); } $this->return_values = $return_values; } catch (Exception $e) { //$this->getResponse()->setHttpStatus(400); return $this->renderJSON(array('failed' => true, 'error' => $e->getMessage())); } }
public function runFindDuplicateIssue(TBGRequest $request) { $status = 200; $message = null; if ($issue_id = $request['issue_id']) { try { $issue = TBGContext::factory()->TBGIssue($issue_id); } catch (Exception $e) { $status = 400; $message = TBGContext::getI18n()->__('Could not find this issue'); } } else { $status = 400; $message = TBGContext::getI18n()->__('Please provide an issue number'); } $searchfor = $request['searchfor']; if (mb_strlen(trim($searchfor)) < 3 && !is_numeric($searchfor)) { $status = 400; $message = TBGContext::getI18n()->__('Please enter something to search for (3 characters or more) %searchfor', array('searchfor' => $searchfor)); } $this->getResponse()->setHttpStatus($status); if ($status == 400) { return $this->renderJSON(array('error' => $message)); } list($issues, $count) = TBGIssue::findIssuesByText($searchfor, $this->selected_project); return $this->renderJSON(array('content' => $this->getComponentHTML('main/findduplicateissues', array('issue' => $issue, 'issues' => $issues, 'count' => $count)))); }
public function applyToIssue(TBGIssue $issue) { $issue->setWorkflowStep($this); if ($this->hasLinkedStatus()) { $issue->setStatus($this->getLinkedStatusID()); } if ($this->isClosed()) { $issue->close(); } else { $issue->open(); } }
?> "> <td><?php echo tbg_formatTime($spent_time->getEditedAt(), 20); ?> </td> <td style="font-size: 0.9em;"><?php echo $spent_time->getActivityType() instanceof TBGActivityType ? $spent_time->getActivityType()->getName() : '-'; ?> </td> <td><?php echo include_component('main/userdropdown', array('user' => $spent_time->getUser())); ?> </td> <td style="text-align: right;"><?php echo TBGIssue::getFormattedTime($spent_time->getSpentTime()); ?> </td> <td style="text-align: right;" class="button-group" <?php if ($spent_time->getComment()) { ?> rowspan="2"<?php } ?> > <a href="javascript:void(0);" style="float: none;" class="button button-silver last" onclick="TBG.Main.Helpers.Backdrop.show('<?php echo make_url('get_partial_for_backdrop', array('key' => 'issue_spenttime', 'entry_id' => $spent_time->getID())); ?> ');"><?php echo __('Edit'); ?>
public function runBulkUpdateIssues(TBGRequest $request) { $issue_ids = $request['issue_ids']; $options = array('issue_ids' => array_values($issue_ids)); TBGContext::loadLibrary('common'); $options['last_updated'] = tbg_formatTime(time(), 20); if (!empty($issue_ids)) { $options['bulk_action'] = $request['bulk_action']; switch ($request['bulk_action']) { case 'assign_milestone': $milestone = null; if ($request['milestone'] == 'new') { $milestone = new TBGMilestone(); $milestone->setProject(TBGContext::getCurrentProject()); $milestone->setName($request['milestone_name']); $milestone->save(); $options['milestone_url'] = TBGContext::getRouting()->generate('project_planning_milestone', array('project_key' => $milestone->getProject()->getKey(), 'milestone_id' => $milestone->getID())); } elseif ($request['milestone']) { $milestone = new TBGMilestone($request['milestone']); } $milestone_id = $milestone instanceof TBGMilestone ? $milestone->getID() : null; foreach (array_keys($issue_ids) as $issue_id) { if (is_numeric($issue_id)) { $issue = new TBGIssue($issue_id); $issue->setMilestone($milestone_id); $issue->save(); } } $options['milestone_id'] = $milestone_id; $options['milestone_name'] = $milestone_id ? $milestone->getName() : '-'; break; case 'set_status': if (is_numeric($request['status'])) { $status = new TBGStatus($request['status']); foreach (array_keys($issue_ids) as $issue_id) { if (is_numeric($issue_id)) { $issue = new TBGIssue($issue_id); $issue->setStatus($status->getID()); $issue->save(); } } $options['status'] = array('color' => $status->getColor(), 'name' => $status->getName(), 'id' => $status->getID()); } break; case 'set_severity': if (is_numeric($request['severity'])) { $severity = $request['severity'] ? new TBGSeverity($request['severity']) : null; foreach (array_keys($issue_ids) as $issue_id) { if (is_numeric($issue_id)) { $issue = new TBGIssue($issue_id); $severity_id = $severity instanceof TBGSeverity ? $severity->getID() : 0; $issue->setSeverity($severity_id); $issue->save(); } } $options['severity'] = array('name' => $severity instanceof TBGSeverity ? $severity->getName() : '-', 'id' => $severity instanceof TBGSeverity ? $severity->getID() : 0); } break; case 'set_resolution': if (is_numeric($request['resolution'])) { $resolution = $request['resolution'] ? new TBGResolution($request['resolution']) : null; foreach (array_keys($issue_ids) as $issue_id) { if (is_numeric($issue_id)) { $issue = new TBGIssue($issue_id); $resolution_id = $resolution instanceof TBGResolution ? $resolution->getID() : 0; $issue->setResolution($resolution_id); $issue->save(); } } $options['resolution'] = array('name' => $resolution instanceof TBGResolution ? $resolution->getName() : '-', 'id' => $resolution instanceof TBGResolution ? $resolution->getID() : 0); } break; case 'set_priority': if (is_numeric($request['priority'])) { $priority = $request['priority'] ? new TBGPriority($request['priority']) : null; foreach (array_keys($issue_ids) as $issue_id) { if (is_numeric($issue_id)) { $issue = new TBGIssue($issue_id); $priority_id = $priority instanceof TBGPriority ? $priority->getID() : 0; $issue->setPriority($priority_id); $issue->save(); } } $options['priority'] = array('name' => $priority instanceof TBGPriority ? $priority->getName() : '-', 'id' => $priority instanceof TBGPriority ? $priority->getID() : 0); } break; case 'set_category': if (is_numeric($request['category'])) { $category = $request['category'] ? new TBGCategory($request['category']) : null; foreach (array_keys($issue_ids) as $issue_id) { if (is_numeric($issue_id)) { $issue = new TBGIssue($issue_id); $category_id = $category instanceof TBGCategory ? $category->getID() : 0; $issue->setCategory($category_id); $issue->save(); } } $options['category'] = array('name' => $category instanceof TBGCategory ? $category->getName() : '-', 'id' => $category instanceof TBGCategory ? $category->getID() : 0); } break; } } return $this->renderJSON($options); }
echo __("Pain bug type on issue changed: %previous_value => %new_value", array('%previous_value' => '<strong>' . $previous_value . '</strong>', '%new_value' => '<strong>' . $new_value . '</strong>')); } break; case TBGLogTable::LOG_ISSUE_PAIN_EFFECT: echo image_tag('icon_priority.png'); if ($item->hasChangeDetails()) { $previous_value = $item->getPreviousValue() ? TBGIssue::getPainTypesOrLabel('pain_effect', $item->getPreviousValue()) : __('Not determined'); $new_value = $item->getCurrentValue() ? TBGIssue::getPainTypesOrLabel('pain_effect', $item->getCurrentValue()) : __('Not determined'); echo __("Pain effect on issue changed: %previous_value => %new_value", array('%previous_value' => '<strong>' . $previous_value . '</strong>', '%new_value' => '<strong>' . $new_value . '</strong>')); } break; case TBGLogTable::LOG_ISSUE_PAIN_LIKELIHOOD: echo image_tag('icon_priority.png'); if ($item->hasChangeDetails()) { $previous_value = $item->getPreviousValue() ? TBGIssue::getPainTypesOrLabel('pain_likelihood', $item->getPreviousValue()) : __('Not determined'); $new_value = $item->getCurrentValue() ? TBGIssue::getPainTypesOrLabel('pain_likelihood', $item->getCurrentValue()) : __('Not determined'); echo __("Likelihood on issue changed: %previous_value => %new_value", array('%previous_value' => '<strong>' . $previous_value . '</strong>', '%new_value' => '<strong>' . $new_value . '</strong>')); } break; case TBGLogTable::LOG_ISSUE_PAIN_CALCULATED: echo image_tag('icon_percent.png'); if ($item->hasChangeDetails()) { echo __("Calculated pain on issue changed: %value", array('%value' => '<strong>' . $item->getText() . '</strong>')); } break; case TBGLogTable::LOG_ISSUE_USERS: 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 __("User working on issue changed: %previous_value => %new_value", array('%previous_value' => '<strong>' . $previous_value . '</strong>', '%new_value' => '<strong>' . $new_value . '</strong>'));
public function hasAccess() { $issue_ids = TBGIssueFilesTable::getTable()->getIssuesByFileID($this->getID()); foreach ($issue_ids as $issue_id) { $issue = new TBGIssue($issue_id); if ($issue->hasAccess()) { return true; } } $event = TBGEvent::createNew('core', 'TBGFile::hasAccess', $this); $event->setReturnValue(false); $event->triggerUntilProcessed(); return $event->getReturnValue(); }
echo html_entity_decode($severity, ENT_QUOTES, TBGContext::getI18n()->getCharset()); ?> ","<?php echo html_entity_decode($resolution, ENT_QUOTES, TBGContext::getI18n()->getCharset()); ?> ","<?php echo html_entity_decode($milestone, ENT_QUOTES, TBGContext::getI18n()->getCharset()); ?> ","<?php echo tbg_formatTime($issue->getLastUpdatedTime(), 21); ?> ","<?php echo $percent; ?> ","<?php echo TBGIssue::getFormattedTime($issue->getEstimatedTime()); ?> ","<?php echo $issue->getFormattedTime($issue->getSpentTime()); ?> ","<?php echo $issue->getUserpain(); ?> ","<?php echo $issue->getVotes(); ?> ","<?php echo str_replace('"', '\\"', html_entity_decode($issue->getDescription(), ENT_QUOTES, TBGContext::getI18n()->getCharset())); ?> ", "<?php echo str_replace('"', '\\"', html_entity_decode($reproductionsteps, ENT_QUOTES, TBGContext::getI18n()->getCharset()));
?> _name"<?php if (!$issue->hasSpentTime()) { ?> style="display: none;"<?php } ?> > <a href="javascript:void(0)" onclick="TBG.Main.Helpers.Backdrop.show('<?php echo make_url('get_partial_for_backdrop', array('key' => 'issue_spenttimes', 'issue_id' => $issue->getID())); ?> ');" id="spent_time_<?php echo $issue->getID(); ?> _value"><?php echo TBGIssue::getFormattedTime($issue->getSpentTime()); ?> </a> </span> <span class="faded_out" id="no_spent_time_<?php echo $issue->getID(); ?> "<?php if ($issue->hasSpentTime()) { ?> style="display: none;"<?php } ?> ><?php echo __('No time spent'); ?>
public function getIssueID() { return is_object($this->_issue_id) ? $this->_issue_id->getID() : (int) $this->_issue_id; }