/** * Check if the project id or identifier is valid. * * @param int|string $project_id * @return int|bool */ private function checkProject($project_id) { $project = $this->client->api('project')->show($project_id); if (!isset($project['project']['id'])) { return false; } return $project['project']['id']; }
/** * Load user data from API. * * @param $id */ public function loadUser($id, $reset = FALSE) { if (!isset($this->users[$id]) || $reset) { $user = $this->client->api('user')->show($id); if (!empty($user['user'])) { $this->users[$id] = new User($this, $user['user']); } } return $this->users[$id]; }
/** * Just return the data from runRequest(). * * @param type $path * @param type $decode * * @return array */ public function get($path, $decode = true) { if ($this->useOriginalGetMethod) { return parent::get($path, $decode); } return $this->runRequest($path, 'GET'); }
/** * iterates over a list of issues and deletes them using their Ids. * * @param array $issues The Issue List * @param \Redmine\Api\Issue $issueApi The Issue Api object, optional. * * @return void */ private function deleteIssueList(array $issues, \Redmine\Api\Issue $issueApi = null) { $issueApi = $issueApi ?: $this->client->api('issue'); /* @var $issueApi \Redmine\Api\Issue */ foreach ($issues['issues'] as $issue) { $issueApi->remove($issue['id']); } }
/** * Sync a single harvest time entry. * * @param \Harvest\Model\DayEntry $harvest_entry * * @return bool */ protected function syncEntry(DayEntry $harvest_entry) { // Check spelling. $words = explode(' ', preg_replace('/[^a-z]+/i', ' ', $harvest_entry->get('notes'))); $spelling_errors = array(); foreach ($words as $word) { if (!pspell_check($this->pspellLink, $word)) { $spelling_errors[] = $word; } } if ($spelling_errors) { $this->userTimeEntryErrors[$harvest_entry->get('user-id')]['spelling'][] = ['entry' => $harvest_entry, 'spelling-errors' => $spelling_errors]; } $redmine_issue = $this->getRedmineIssue($harvest_entry); if (!$redmine_issue) { return false; } $existing_redmine_time_entries = $this->getExistingRedmineIssueTimeEntries($redmine_issue, $harvest_entry); // If there are existing Redmine time entries matching this harvest entry and we are not updating, skip. if (count($existing_redmine_time_entries) > 0 && !$this->input->getOption('update')) { return false; } // Or if there is more than one matching redmine time entry, throw an error and continue. if (count($existing_redmine_time_entries) > 1) { $this->output->writeln(sprintf('<error>Multiple Redmine time entries matching harvest time entry %d. See entries %s</error>', $harvest_entry->get('id'), json_encode($existing_redmine_time_entries))); $this->errors = true; return false; } // If Harvest user is not mapped to a redmine user, throw an error and continue. if (!isset($this->userMap[$harvest_entry->get('user-id')])) { $this->output->writeln(sprintf('<error>No mapping is defined for user %d</error>', $harvest_entry->get('user-id'))); $this->errors = true; return false; } // Log the entry. $redmine_entry_params = $this->populateRedmineTimeEntry($redmine_issue, $harvest_entry); // Check rounding. if ($redmine_entry_params['hours'] != $harvest_entry->get('hours')) { $this->userTimeEntryErrors[$harvest_entry->get('user-id')]['rounding'][] = ['entry' => $harvest_entry, 'rounded-hours' => $redmine_entry_params['hours']]; } $save_entry_result = false; $this->setRedmineClient(); if (!$this->input->getOption('dry-run')) { try { $this->redmineClient->setImpersonateUser($this->userMap[$harvest_entry->get('user-id')]); $save_entry_result = $this->saveHarvestTimeEntryToRedmine($redmine_entry_params, $existing_redmine_time_entries); } catch (\Exception $e) { $this->output->writeln(sprintf('<error>Failed to create time entry for redmine issue #%d, harvest id %d, exception %s</error>', $redmine_issue['issue']['id'], $harvest_entry->get('id'), $e->getMessage())); } finally { $this->redmineClient->setImpersonateUser(null); } } if ($save_entry_result || $this->input->getOption('dry-run')) { $this->output->writeln(sprintf('<comment>%s time entry for issue #%d with %s hours (Harvest hours: %s)</comment>', count($existing_redmine_time_entries) > 0 ? 'Updated' : 'Created', $redmine_issue['issue']['id'], $redmine_entry_params['hours'], $harvest_entry->get('hours'))); } return $save_entry_result; }
/** * Create follow up issue to given issue * * @param array $issue */ public function createAction($issue) { $redmineClient = new Redmine\Client($this->settings['Redmine']['url'], $this->settings['Redmine']['apiKey']); $id = $issue['related_id']; unset($issue['related_id']); $params = $issue; // get additional issue data and assign to new issue $res = $redmineClient->api('issue')->show($id); $params['project_id'] = Arrays::getValueByPath($res, 'issue.project.id'); $params['category_id'] = Arrays::getValueByPath($res, 'issue.category.id'); $newIssue = $redmineClient->api('issue')->create($params); // create relation $relation['issue_to_id'] = $id; $relation['relation_type'] = self::RELATION_TYPE; $json = json_encode(array('relation' => $relation)); $redmineClient->post('/issues/' . (string) $newIssue->id . '/relations.json', $json); $this->view->assign('value', json_decode(json_encode((array) $newIssue), 1)); }
/** * Factory method to be implemented from \RedmineCommand\AbstractCommand . * * * Must return an instance of \RedmineCommand\SlackResult . * * @see \RedmineCommand\AbstractCommand::executeImpl() * @return \RedmineCommand\SlackResult */ protected function executeImpl() { $log = $this->log; $result = new SlackResult(); $log->debug("CmdShow: Issues Id: " . implode(",", $this->cmd)); $client = new Client($this->config->redmine_url, $this->config->redmine_api_key); $resultText = "[requested by " . $this->post["user_name"] . "]"; if (empty($this->cmd)) { $resultText .= " Issue number required!"; } else { $resultText .= " Issue Details: "; } // Fetching issues and adding them as slack attachments $attachments = array(); $attachmentUnknown = null; foreach ($this->cmd as $issueId) { $log->debug("CmdShow: calling Redmine api for issue id #{$issueId}"); $issue = $client->api('issue')->show((int) $issueId); $attachment = new SlackResultAttachment(); if (!is_array($issue)) { if (strcmp($issue, "Syntax error") == 0) { if ($attachmentUnknown == null) { $attachmentUnknown = new SlackResultAttachment(); $attachmentUnknown->setTitle("Unknown Issues:"); $attachmentUnknown->setText(""); } $log->debug("CmdShow: #{$issueId} issue unknown!"); $attachmentUnknown->setText($attachmentUnknown->getText() . " {$issueId}"); } } else { $log->debug("CmdShow: #{$issueId} issue found!"); $attachment = Util::convertIssueToAttachment($this->config->getRedmineIssuesUrl(), $issueId, $issue); $attachments[] = $attachment; } } $result->setText($resultText); if ($attachmentUnknown != null) { $attachments[] = $attachmentUnknown; } $result->setAttachmentsArray($attachments); return $result; }
/** * Authenticate to remote API * @return Redmine */ protected function authenticate() { $redmine = new Redmine($this->redmineProtocol . $this->redmineUrl, $this->redmineToken); $redmine->setPort($this->redminePort); return $redmine; }
/** * Perform the client delete() method. * * @param string $path * * @return array */ protected function delete($path) { return $this->client->delete($path); }
/** * @covers Redmine\Client * @test * @dataProvider getApiClassesProvider */ public function shouldGetApiInstance($apiName, $class) { $client = new Client('http://test.local', 'asdf'); $this->assertInstanceOf($class, $client->api($apiName)); }
function it_presents_a_summary_before_initiating_the_migration(Client $redmine, Project $project) { $project_detail = ['project' => ['name' => 'Redmine Project']]; $redmine->api('project')->willReturn($project); $project->show(34)->willReturn($project_detail); $mock = PHPMockery::mock('\\Ttf\\Remaim', 'fgets')->andReturn('y'); $phabricator_project = ['name' => 'Phabricator Project', 'id' => 78]; $policies = ['view' => 'PHID-foobar', 'edit' => 'PHID-barbaz']; $tasks = ['total_count' => [10]]; ob_start(); $this->presentSummary(34, $phabricator_project, $tasks, $policies)->shouldReturn(true); $output = ob_get_clean(); expect($output)->toBe(PHP_EOL . PHP_EOL . '####################' . PHP_EOL . '# Pre-flight check #' . PHP_EOL . '####################' . PHP_EOL . 'Redmine project named "Redmine Project" with ID 34.' . PHP_EOL . 'Target phabricator project named "Phabricator Project" with ID 78.' . PHP_EOL . 'View policy: PHID-foobar, Edit policy: PHID-barbaz' . PHP_EOL . '10 tickets to be migrated!' . PHP_EOL . PHP_EOL . 'OK to continue? [y/N]:' . PHP_EOL . '> '); }