Ejemplo n.º 1
0
 /**
  * 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;
 }
Ejemplo n.º 2
0
 /**
  * @covers Redmine\Client
  * @test
  */
 public function testPrepareDeleteUploadRequestWithSslAndImpersonateUser()
 {
     // Create the object under test
     $client = new Client('https://test.local', 'USER_API-KEY159');
     $client->setImpersonateUser('test_user');
     $client->setUseHttpAuth(false);
     $client->setCheckSslCertificate(true);
     $client->setCheckSslHost(true);
     // Perform the tests
     $data = array(1 => 'post_1', '25' => 'post_25');
     $client->prepareRequest('/uploads.xml', 'DELETE', $data);
     $curlOptions = $client->getCurlOptions();
     $this->assertArrayNotHasKey(CURLOPT_USERPWD, $curlOptions);
     $this->assertArrayNotHasKey(CURLOPT_HTTPAUTH, $curlOptions);
     $this->assertSame('https://test.local/uploads.xml', $curlOptions[CURLOPT_URL]);
     $this->assertSame(0, $curlOptions[CURLOPT_VERBOSE]);
     $this->assertSame(0, $curlOptions[CURLOPT_HEADER]);
     $this->assertSame(1, $curlOptions[CURLOPT_RETURNTRANSFER]);
     $this->assertSame(443, $curlOptions[CURLOPT_PORT]);
     $this->assertSame(1, $curlOptions[CURLOPT_SSL_VERIFYPEER]);
     $this->assertSame(2, $curlOptions[CURLOPT_SSL_VERIFYHOST]);
     $this->assertContains('Expect: ', $curlOptions[CURLOPT_HTTPHEADER]);
     $this->assertContains('Content-Type: application/octet-stream', $curlOptions[CURLOPT_HTTPHEADER]);
     $this->assertContains('X-Redmine-Switch-User: test_user', $curlOptions[CURLOPT_HTTPHEADER]);
     $this->assertContains('X-Redmine-API-Key: USER_API-KEY159', $curlOptions[CURLOPT_HTTPHEADER]);
     $this->assertSame('DELETE', $curlOptions[CURLOPT_CUSTOMREQUEST]);
 }