/** * Add a comment on GitHub. * * @param TrackerProject $project The project. * @param integer $issueNumber The issue number. * @param string $comment The comment to add. * @param string $userName The username. * @param DatabaseDriver $database The database driver object. * * @return Comment The GitHub comment object * * @throws \DomainException * * @since 1.0 */ public function addComment(TrackerProject $project, $issueNumber, $comment, $userName, DatabaseDriver $database) { $data = new Comment(); if ($project->gh_user && $project->gh_project) { $gitHubResponse = $this->gitHub->issues->comments->create($project->gh_user, $project->gh_project, $issueNumber, $comment); if (!isset($gitHubResponse->id)) { throw new \DomainException('Invalid response from GitHub'); } $data->created_at = $gitHubResponse->created_at; $data->opened_by = $gitHubResponse->user->login; $data->comment_id = $gitHubResponse->id; $data->text_raw = $gitHubResponse->body; $data->text = $this->gitHub->markdown->render($comment, 'gfm', $project->gh_user . '/' . $project->gh_project); } else { $date = new Date(); $data->created_at = $date->format($database->getDateFormat()); $data->opened_by = $userName; $data->comment_id = '???'; $data->text_raw = $comment; $data->text = $this->gitHub->markdown->render($comment, 'markdown'); } (new ActivityModel($database))->addActivityEvent('comment', $data->created_at, $data->opened_by, $project->project_id, $issueNumber, $data->comment_id, $data->text, $data->text_raw); $data->activities_id = $database->insertid(); $date = new Date($data->created_at); $data->created_at = $date->format('j M Y'); return $data; }
/** * Verify the default values for the log entry object. * * @return void * * @since 1.0 * @covers Joomla\Log\LogEntry::__construct */ public function testDefaultValues() { $tmp = new LogEntry('Lorem ipsum dolor sit amet'); $date = new Date('now'); // Message. $this->assertThat($tmp->message, $this->equalTo('Lorem ipsum dolor sit amet'), 'Line: ' . __LINE__ . '.'); // Priority. $this->assertThat($tmp->priority, $this->equalTo(Log::INFO), 'Line: ' . __LINE__ . '.'); // Category. $this->assertThat($tmp->category, $this->equalTo(''), 'Line: ' . __LINE__ . '.'); // Date. $this->assertThat($tmp->date->toISO8601(), $this->equalTo($date->toISO8601()), 'Line: ' . __LINE__ . '.'); }
/** * Prepare the response. * * @return mixed * * @since 1.0 * @throws \Exception */ protected function prepareResponse() { $this->getContainer()->get('app')->getUser()->authorize('create'); $comment = $this->getContainer()->get('app')->input->get('text', '', 'raw'); $issue_number = $this->getContainer()->get('app')->input->getInt('issue_number'); if (!$issue_number) { throw new \Exception('No issue number received.'); } if (!$comment) { throw new \Exception('You should write a comment first...'); } // @todo removeMe :( $comment .= sprintf('<br /><br />*This comment was created with the <a href="%1$s">%2$s Application</a> at <a href="%3$s">%4$s</a>.*', 'https://github.com/joomla/jissues', 'J!Tracker', $this->getContainer()->get('app')->get('uri')->base->full, $this->getContainer()->get('app')->get('uri')->base->full); $project = $this->getContainer()->get('app')->getProject(); /* @type \Joomla\Github\Github $github */ $github = $this->getContainer()->get('gitHub'); $data = new \stdClass(); $db = $this->getContainer()->get('db'); if ($project->gh_user && $project->gh_project) { $gitHubResponse = $github->issues->comments->create($project->gh_user, $project->gh_project, $issue_number, $comment); if (!isset($gitHubResponse->id)) { throw new \Exception('Invalid response from GitHub'); } $data->created_at = $gitHubResponse->created_at; $data->opened_by = $gitHubResponse->user->login; $data->comment_id = $gitHubResponse->id; $data->text_raw = $gitHubResponse->body; $data->text = $github->markdown->render($comment, 'gfm', $project->gh_user . '/' . $project->gh_project); } else { $date = new Date(); $data->created_at = $date->format($db->getDateFormat()); $data->opened_by = $this->getContainer()->get('app')->getUser()->username; $data->comment_id = '???'; $data->text_raw = $comment; $data->text = $github->markdown->render($comment, 'markdown'); } $table = new ActivitiesTable($db); $table->event = 'comment'; $table->created_date = $data->created_at; $table->project_id = $project->project_id; $table->issue_number = $issue_number; $table->gh_comment_id = $data->comment_id; $table->user = $data->opened_by; $table->text = $data->text; $table->text_raw = $data->text_raw; $table->store(); $data->activities_id = $table->activities_id; $this->response->data = $data; $this->response->message = g11n3t('Your comment has been submitted'); }
/** * Prepare the response. * * @return mixed * * @since 1.0 * @throws \Exception */ protected function prepareResponse() { /* @type \JTracker\Application $application */ $application = $this->getContainer()->get('app'); $application->getUser()->authorize('create'); $comment = $application->input->get('text', '', 'raw'); $issue_number = $application->input->getInt('issue_number'); $project = $application->getProject(); if (!$issue_number) { throw new \Exception('No issue number received.'); } if (!$comment) { throw new \Exception('You should write a comment first...'); } // @todo removeMe :( $comment .= sprintf('<hr /><sub>This comment was created with the <a href="%1$s">%2$s Application</a> at <a href="%3$s">%4$s</a>.</sub>', 'https://github.com/joomla/jissues', 'J!Tracker', $application->get('uri')->base->full . 'tracker/' . $project->alias . '/' . $issue_number, str_replace(['http://', 'https://'], '', $application->get('uri')->base->full) . $project->alias . '/' . $issue_number); /* @type \Joomla\Github\Github $github */ $github = $this->getContainer()->get('gitHub'); $data = new \stdClass(); /* @type \Joomla\Database\DatabaseDriver $db */ $db = $this->getContainer()->get('db'); if ($project->gh_user && $project->gh_project) { $gitHubResponse = $github->issues->comments->create($project->gh_user, $project->gh_project, $issue_number, $comment); if (!isset($gitHubResponse->id)) { throw new \Exception('Invalid response from GitHub'); } $data->created_at = $gitHubResponse->created_at; $data->opened_by = $gitHubResponse->user->login; $data->comment_id = $gitHubResponse->id; $data->text_raw = $gitHubResponse->body; $data->text = $github->markdown->render($comment, 'gfm', $project->gh_user . '/' . $project->gh_project); } else { $date = new Date(); $data->created_at = $date->format($db->getDateFormat()); $data->opened_by = $application->getUser()->username; $data->comment_id = '???'; $data->text_raw = $comment; $data->text = $github->markdown->render($comment, 'markdown'); } (new ActivityModel($db))->addActivityEvent('comment', $data->created_at, $data->opened_by, $project->project_id, $issue_number, $data->comment_id, $data->text, $data->text_raw); $data->activities_id = $db->insertid(); $date = new Date($data->created_at); $data->created_at = $date->format('j M Y'); $this->response->data = $data; $this->response->message = g11n3t('Your comment has been submitted'); }
/** * Method to get the list of comments in a repository. * * @param string $owner The name of the owner of the GitHub repository. * @param string $repo The name of the GitHub repository. * @param string $sort The sort field - created or updated. * @param string $direction The sort order- asc or desc. Ignored without sort parameter. * @param Date $since A timestamp in ISO 8601 format. * * @throws \UnexpectedValueException * @throws \DomainException * @since 1.0 * * @return array */ public function getRepositoryList($owner, $repo, $sort = 'created', $direction = 'asc', Date $since = null) { // Build the request path. $path = '/repos/' . $owner . '/' . $repo . '/issues/comments'; if (false == in_array($sort, array('created', 'updated'))) { throw new \UnexpectedValueException(sprintf('%1$s - sort field must be "created" or "updated"', __METHOD__)); } if (false == in_array($direction, array('asc', 'desc'))) { throw new \UnexpectedValueException(sprintf('%1$s - direction field must be "asc" or "desc"', __METHOD__)); } $path .= '?sort=' . $sort; $path .= '&direction=' . $direction; if ($since) { $path .= '&since=' . $since->toISO8601(); } // Send the request. return $this->processResponse($this->client->get($this->fetchUrl($path))); }
/** * Method to list commits for a repository. * * A special note on pagination: Due to the way Git works, commits are paginated based on SHA * instead of page number. * Please follow the link headers as outlined in the pagination overview instead of constructing * page links yourself. * * @param string $user The name of the owner of the GitHub repository. * @param string $repo The name of the GitHub repository. * @param string $sha Sha or branch to start listing commits from. * @param string $path Only commits containing this file path will be returned. * @param string $author GitHub login, name, or email by which to filter by commit author. * @param Date $since ISO 8601 Date - Only commits after this date will be returned. * @param Date $until ISO 8601 Date - Only commits before this date will be returned. * * @throws \DomainException * @since 1.0 * * @return array */ public function getList($user, $repo, $sha = '', $path = '', $author = '', Date $since = null, Date $until = null) { // Build the request path. $rPath = '/repos/' . $user . '/' . $repo . '/commits?'; $rPath .= $sha ? '&sha=' . $sha : ''; $rPath .= $path ? '&path=' . $path : ''; $rPath .= $author ? '&author=' . $author : ''; $rPath .= $since ? '&since=' . $since->toISO8601() : ''; $rPath .= $until ? '&until=' . $until->toISO8601() : ''; // Send the request. $response = $this->client->get($this->fetchUrl($rPath)); // Validate the response code. if ($response->code != 200) { // Decode the error response and throw an exception. $error = json_decode($response->body); throw new \DomainException($error->message, $response->code); } return json_decode($response->body); }
/** * Set the last visited time for a newly logged in user * * @param integer $id The user ID to update * * @return void * * @since 1.0 */ public function setLastVisitTime($id) { /* @type \Joomla\Database\DatabaseDriver $db */ $db = $this->container->get('db'); $date = new Date(); $db->setQuery($db->getQuery(true)->update($db->quoteName('#__users'))->set($db->quoteName('lastvisitDate') . '=' . $db->quote($date->format($db->getDateFormat())))->where($db->quoteName('id') . '=' . (int) $id))->execute(); }
/** * Add a new event and store it to the database. * * @param string $event The event name. * @param string $dateTime Date and time. * @param string $userName User name. * @param integer $projectId Project id. * @param integer $itemNumber THE item number. * @param integer $commentId The comment id * @param string $text The parsed html comment text. * @param string $textRaw The raw comment text. * * @return $this * * @since 1.0 */ protected function addActivityEvent($event, $dateTime, $userName, $projectId, $itemNumber, $commentId = null, $text = '', $textRaw = '') { $data = array(); $date = new Date($dateTime); $data['created_date'] = $date->format($this->db->getDateFormat()); $data['event'] = $event; $data['user'] = $userName; $data['project_id'] = (int) $projectId; $data['issue_number'] = (int) $itemNumber; $data['gh_comment_id'] = (int) $commentId; $data['text'] = $text; $data['text_raw'] = $textRaw; try { $activity = new ActivitiesTable($this->db); $activity->save($data); } catch (\Exception $exception) { $this->logger->info(sprintf('Error storing %s activity to the database (ProjectId: %d, ItemNo: %d): %s', $event, $projectId, $itemNumber, $exception->getMessage())); $this->getContainer()->get('app')->close(); } return $this; }
/** * Method to update data for an issue from GitHub * * @return boolean True on success * * @since 1.0 */ protected function updateData() { $table = new IssuesTable($this->db); try { $table->load(array('issue_number' => $this->hookData->issue->number, 'project_id' => $this->project->project_id)); } catch (\Exception $e) { $this->logger->error(sprintf('Error loading GitHub issue %s/%s #%d in the tracker: %s', $this->project->gh_user, $this->project->gh_project, $this->hookData->issue->number, $e->getMessage())); $this->getContainer()->get('app')->close(); } // Figure out the state based on the action $action = $this->hookData->action; $status = $this->processStatus($action, $table->status); // Try to render the description with GitHub markdown $parsedText = $this->parseText($this->hookData->issue->body); // Prepare the dates for insertion to the database $dateFormat = $this->db->getDateFormat(); $modified = new Date($this->hookData->issue->updated_at); // Only update fields that may have changed, there's no API endpoint to show that so make some guesses $data = array(); $data['id'] = $table->id; $data['title'] = $this->hookData->issue->title; $data['description'] = $parsedText; $data['description_raw'] = $this->hookData->issue->body; $data['status'] = is_null($status) ? $table->status : $status; $data['modified_date'] = $modified->format($dateFormat); $data['modified_by'] = $this->hookData->sender->login; // Add the closed date if the status is closed if ($this->hookData->issue->closed_at) { $closed = new Date($this->hookData->issue->closed_at); $data['closed_date'] = $closed->format($dateFormat); } // Process labels for the item $data['labels'] = $this->processLabels($this->hookData->issue->number); // Grab some data based on the existing record $data['priority'] = $table->priority; $data['build'] = $table->build; $data['rel_number'] = $table->rel_number; $data['rel_type'] = $table->rel_type; $data['milestone_id'] = $table->milestone_id; if (empty($data['build'])) { $data['build'] = $this->hookData->repository->default_branch; } $model = (new IssueModel($this->db))->setProject(new TrackerProject($this->db, $this->project)); // Check if the state has changed (e.g. open/closed) $oldState = $model->getOpenClosed($table->status); $state = is_null($status) ? $oldState : $model->getOpenClosed($data['status']); $data['old_state'] = $oldState; $data['new_state'] = $state; try { $model->save($data); } catch (\Exception $e) { $this->logger->error(sprintf('Error updating GitHub issue %s/%s #%d (Database ID #%d) in the tracker: %s', $this->project->gh_user, $this->project->gh_project, $this->hookData->issue->number, $table->id, $e->getMessage())); $this->getContainer()->get('app')->close(); } // Refresh the table object for the listeners $table->load($data['id']); $this->triggerEvent('onIssueAfterUpdate', $table); // Add a reopen record to the activity table if the status is closed if ($action == 'reopened') { $this->addActivityEvent('reopen', $this->hookData->issue->updated_at, $this->hookData->sender->login, $this->project->project_id, $this->hookData->issue->number); } // Add a close record to the activity table if the status is closed if ($this->hookData->issue->closed_at) { $this->addActivityEvent('close', $this->hookData->issue->closed_at, $this->hookData->sender->login, $this->project->project_id, $this->hookData->issue->number); } // Store was successful, update status $this->logger->info(sprintf('Updated GitHub issue %s/%s #%d (Database ID #%d) to the tracker.', $this->project->gh_user, $this->project->gh_project, $this->hookData->issue->number, $table->id)); return true; }
/** * Load data by a given user name. * * @param string $userName The user name * * @return TableUsers * * @since 1.0 */ public function loadByUserName($userName) { $db = $this->database; $table = new TableUsers($db); $table->loadByUserName($userName); if (!$table->id) { // Register a new user $date = new Date(); $this->registerDate = $date->format($db->getDateFormat()); $table->save($this); } $this->id = $table->id; $this->params->loadString($table->params); $this->loadAccessGroups(); return $this; }
/** * Testing setTimezone * * @param string $tz Which Time Zone should it be? * @param string $expected What should the resulting time string look like? * * @return void * * @dataProvider seedTestSetTimezone * @since 1.0 * @covers Joomla\Date\Date::setTimezone */ public function testSetTimezone($tz, $expected) { $this->instance->setTimezone(new \DateTimeZone($tz)); $this->assertThat($this->instance->format('r', true), $this->equalTo($expected)); }
/** * Execute the controller. * * @return string The rendered view. * * @since 1.0 * @throws \JTracker\Authentication\Exception\AuthenticationException * @throws \RuntimeException * @throws \UnexpectedValueException */ public function execute() { /* @type \JTracker\Application $application */ $application = $this->getContainer()->get('app'); $src = $application->input->get('item', array(), 'array'); $user = $application->getUser(); $project = $application->getProject(); $model = new IssueModel($this->getContainer()->get('db')); $model->setProject($project); $issueNumber = isset($src['issue_number']) ? (int) $src['issue_number'] : 0; if (!$issueNumber) { throw new \UnexpectedValueException('No issue number received.'); } $item = $model->getItem($issueNumber); $data = array(); if ($user->check('edit')) { // The user has full "edit" permission. $data = $src; // Allow admins to update labels and milestones if (!$user->check('manage')) { if (!empty($item->labels)) { $data['labels'] = explode(',', $item->labels); } $data['milestone_id'] = $item->milestone_id; } } elseif ($user->canEditOwn($item->opened_by)) { // The user has "edit own" permission. $data['id'] = (int) $src['id']; $data['issue_number'] = (int) $src['issue_number']; $data['title'] = $src['title']; $data['description_raw'] = $src['description_raw']; // Take the remaining values from the stored item if (!empty($item->labels)) { $data['labels'] = explode(',', $item->labels); } $data['status'] = $item->status; $data['priority'] = $item->priority; $data['build'] = $item->build; $data['rel_number'] = $item->rel_number; $data['rel_type'] = $item->rel_type; $data['easy'] = $item->easy; $data['milestone_id'] = $item->milestone_id; } else { // The user has no "edit" permission. throw new AuthenticationException($user, 'edit'); } $gitHub = GithubFactory::getInstance($application); // Check if the state has changed (e.g. open/closed) $oldState = $model->getOpenClosed($item->status); $state = $model->getOpenClosed($data['status']); // Project is managed on GitHub if ($project->gh_user && $project->gh_project) { // @todo assignee $assignee = null; // Prepare labels $ghLabels = []; if (!empty($data['labels'])) { foreach ($project->getLabels() as $id => $label) { if (in_array($id, $data['labels'])) { $ghLabels[] = $label->name; } } } // Prepare milestone $ghMilestone = null; if (!empty($data['milestone_id'])) { foreach ($project->getMilestones() as $milestone) { if ($milestone->milestone_id == $data['milestone_id']) { $ghMilestone = $milestone->milestone_number; } } } try { $gitHubResponse = $this->updateGitHub($item->issue_number, $data, $state, $oldState, $assignee, $ghMilestone, $ghLabels); // Set the modified_date from GitHub (important!) $data['modified_date'] = $gitHubResponse->updated_at; } catch (GithubException $exception) { $this->getContainer()->get('app')->getLogger()->error(sprintf('Error code %1$s received from GitHub when editing an issue with the following data:' . ' GitHub User: %2$s; GitHub Repo: %3$s; Issue Number: %4$s; State: %5$s, Old state: %6$s' . ' The error message returned was: %7$s', $exception->getCode(), $project->gh_user, $project->gh_project, $item->issue_number, $state, $oldState, $exception->getMessage())); throw new \RuntimeException('Invalid response from GitHub'); } // Render the description text using GitHub's markdown renderer. $data['description'] = $gitHub->markdown->render($data['description_raw'], 'gfm', $project->gh_user . '/' . $project->gh_project); } else { // Project is managed by JTracker only // Render the description text using GitHub's markdown renderer. $data['description'] = $gitHub->markdown->render($src['description_raw'], 'markdown'); $data['modified_date'] = (new Date())->format($this->getContainer()->get('db')->getDateFormat()); } try { $data['modified_by'] = $user->username; // If the user have edit permission, let him / her modify the categories. if ($user->check('edit')) { $categoryModel = new CategoryModel($this->getContainer()->get('db')); $category['issue_id'] = $data['id']; $category['modified_by'] = $user->username; $category['categories'] = $application->input->get('categories', null, 'array'); $category['issue_number'] = $data['issue_number']; $category['project_id'] = $project->project_id; $categoryModel->updateCategory($category); } // Pass the old and new states into the save method $data['old_state'] = $oldState; $data['new_state'] = $state; // Values that are not supposed to change. $data['commits'] = $item->commits; $data['pr_head_sha'] = $item->pr_head_sha; // Save the record. $model->save($data); $comment = $application->input->get('comment', '', 'raw'); // Save the comment. if ($comment) { /* @type \JTracker\Github\Github $github */ $github = $this->getContainer()->get('gitHub'); $project = $application->getProject(); $gitHubHelper = new GitHubHelper($github); $comment .= $gitHubHelper->getApplicationComment($application, $project, $issueNumber); $data = new \stdClass(); $db = $this->getContainer()->get('db'); if ($project->gh_user && $project->gh_project) { $gitHubResponse = $github->issues->comments->create($project->gh_user, $project->gh_project, $issueNumber, $comment); if (!isset($gitHubResponse->id)) { throw new \RuntimeException('Invalid response from GitHub'); } $data->created_at = $gitHubResponse->created_at; $data->opened_by = $gitHubResponse->user->login; $data->comment_id = $gitHubResponse->id; $data->text_raw = $gitHubResponse->body; $data->text = $github->markdown->render($comment, 'gfm', $project->gh_user . '/' . $project->gh_project); } else { $date = new Date(); $data->created_at = $date->format($db->getDateFormat()); $data->opened_by = $application->getUser()->username; $data->comment_id = '???'; $data->text_raw = $comment; $data->text = $github->markdown->render($comment, 'markdown'); } $table = new ActivitiesTable($db); $table->event = 'comment'; $table->created_date = $data->created_at; $table->project_id = $project->project_id; $table->issue_number = $issueNumber; $table->gh_comment_id = $data->comment_id; $table->user = $data->opened_by; $table->text = $data->text; $table->text_raw = $data->text_raw; $table->store(); } $application->enqueueMessage('The changes have been saved.', 'success')->redirect('/tracker/' . $application->input->get('project_alias') . '/' . $issueNumber); } catch (\RuntimeException $exception) { $application->enqueueMessage($exception->getMessage(), 'error'); // @todo preserve data when returning to edit view on failure. $application->redirect($application->get('uri.base.path') . 'tracker/' . $application->input->get('project_alias') . '/' . $issueNumber . '/edit'); } return parent::execute(); }
public function setLastVisit($id) { if ($id) { $date = new Date(); $this->store(array('id' => $id, 'lastvisitDate' => $date->__toString())); } }
/** * Testing toUnix * * @param mixed $tz Which time zone? (can be string or numeric * @param string $setTime What time should be set? * @param string $expected What should the resulting time string look like? * * @return void * * @dataProvider seedTestToUnix * @since 1.0 * @covers Joomla\Date\Date::toUnix */ public function testToUnix($tz, $setTime, $expected) { if (is_null($tz)) { $testDate = new Date($setTime); } else { $testDate = new Date($setTime, $tz); } $this->assertThat($testDate->toUnix(), $this->equalTo($expected)); }
/** * Method to update data for an issue from GitHub * * @return boolean True on success * * @since 1.0 */ protected function updateData() { $table = new IssuesTable($this->db); try { $table->load(array('issue_number' => $this->data->number, 'project_id' => $this->project->project_id)); } catch (\Exception $e) { $this->setStatusCode($e->getCode()); $logMessage = sprintf('Error loading GitHub issue %s/%s #%d in the tracker: %s', $this->project->gh_user, $this->project->gh_project, $this->data->number, $e->getMessage()); $this->response->error = $logMessage; $this->logger->error($logMessage); return false; } // Figure out the state based on the action $action = $this->hookData->action; $status = $this->processStatus($action, $table->status); // Try to render the description with GitHub markdown $parsedText = $this->parseText($this->data->body); // Prepare the dates for insertion to the database $dateFormat = $this->db->getDateFormat(); $modified = new Date($this->data->updated_at); // Only update fields that may have changed, there's no API endpoint to show that so make some guesses $data = array(); $data['id'] = $table->id; $data['title'] = $this->data->title; $data['description'] = $parsedText; $data['description_raw'] = $this->data->body; $data['status'] = is_null($status) ? $table->status : $status; $data['modified_date'] = $modified->format($dateFormat); $data['modified_by'] = $this->hookData->sender->login; // Add the closed date if the status is closed if ($this->data->closed_at) { $closed = new Date($this->data->closed_at); $data['closed_date'] = $closed->format($dateFormat); } // Process labels for the item $data['labels'] = $this->processLabels($this->data->number); // Grab some data based on the existing record $data['priority'] = $table->priority; $data['build'] = $table->build; $data['rel_number'] = $table->rel_number; $data['rel_type'] = $table->rel_type; $data['milestone_id'] = $table->milestone_id; if (empty($data['build'])) { $data['build'] = $this->hookData->repository->default_branch; } $model = (new IssueModel($this->db))->setProject(new TrackerProject($this->db, $this->project)); // Check if the state has changed (e.g. open/closed) $oldState = $model->getOpenClosed($table->status); $state = is_null($status) ? $oldState : $model->getOpenClosed($data['status']); $data['old_state'] = $oldState; $data['new_state'] = $state; $gitHubBot = null; if ($this->project->gh_editbot_user && $this->project->gh_editbot_pass) { $gitHubBot = new GitHubHelper(GithubFactory::getInstance($this->getContainer()->get('app'), true, $this->project->gh_editbot_user, $this->project->gh_editbot_pass)); } if ($gitHubBot && $table->pr_head_sha && $table->pr_head_sha != $this->data->head->sha) { // The PR has been updated. $testers = (new IssueModel($this->getContainer()->get('db')))->getAllTests($table->id); if ($testers) { // Send a notification. $comment = "This PR has received new commits.\n\n**CC:** @" . implode(', @', $testers); $comment .= $gitHubBot->getApplicationComment($this->getContainer()->get('app'), $this->project, $table->issue_number); $gitHubBot->addComment($this->project, $table->issue_number, $comment, $this->project->gh_editbot_user, $this->getContainer()->get('db')); } } $data['pr_head_sha'] = $this->data->head->sha; $commits = (new GitHubHelper($this->github))->getCommits($this->project, $this->data->number); $data['commits'] = json_encode($commits); try { $model->save($data); } catch (\Exception $e) { $this->setStatusCode($e->getCode()); $logMessage = sprintf('Error updating GitHub pull request %s/%s #%d (Database ID #%d) to the tracker: %s', $this->project->gh_user, $this->project->gh_project, $this->data->number, $table->id, $e->getMessage()); $this->response->error = $logMessage; $this->logger->error($logMessage); return false; } // Refresh the table object for the listeners $table->load($data['id']); $this->triggerEvent('onPullAfterUpdate', ['table' => $table]); // Add a reopen record to the activity table if the status is reopened if ($action == 'reopened') { $this->addActivityEvent('reopen', $this->data->updated_at, $this->hookData->sender->login, $this->project->project_id, $this->data->number); } // Add a synchronize record to the activity table if the action is synchronized if ($action == 'synchronize') { $this->addActivityEvent('synchronize', $this->data->updated_at, $this->hookData->sender->login, $this->project->project_id, $this->data->number); } // Add a close record to the activity table if the status is closed if ($this->data->closed_at) { $this->addActivityEvent('close', $this->data->closed_at, $this->hookData->sender->login, $this->project->project_id, $this->data->number); } // Store was successful, update status $this->logger->info(sprintf('Updated GitHub pull request %s/%s #%d (Database ID #%d) to the tracker.', $this->project->gh_user, $this->project->gh_project, $this->data->number, $table->id)); return true; }
/** * Method to list issues. * * @param string $user The name of the owner of the GitHub repository. * @param string $repo The name of the GitHub repository. * @param string $milestone The milestone number, 'none', or *. * @param string $state The optional state to filter requests by. [open, closed] * @param string $assignee The assignee name, 'none', or *. * @param string $mentioned The GitHub user name. * @param string $labels The list of comma separated Label names. Example: bug,ui,@high. * @param string $sort The sort order: created, updated, comments, default: created. * @param string $direction The list direction: asc or desc, default: desc. * @param Date $since The date/time since when issues should be returned. * @param integer $page The page number from which to get items. * @param integer $limit The number of items on a page. * * @return object * * @since 1.0 * @throws \DomainException */ public function getListByRepository($user, $repo, $milestone = null, $state = null, $assignee = null, $mentioned = null, $labels = null, $sort = null, $direction = null, Date $since = null, $page = 0, $limit = 0) { // Build the request path. $path = '/repos/' . $user . '/' . $repo . '/issues'; $uri = new Uri($this->fetchUrl($path, $page, $limit)); if ($milestone) { $uri->setVar('milestone', $milestone); } if ($state) { $uri->setVar('state', $state); } if ($assignee) { $uri->setVar('assignee', $assignee); } if ($mentioned) { $uri->setVar('mentioned', $mentioned); } if ($labels) { $uri->setVar('labels', $labels); } if ($sort) { $uri->setVar('sort', $sort); } if ($direction) { $uri->setVar('direction', $direction); } if ($since) { $uri->setVar('since', $since->toISO8601()); } // Send the request. $response = $this->client->get((string) $uri); // Validate the response code. if ($response->code != 200) { // Decode the error response and throw an exception. $error = json_decode($response->body); throw new \DomainException($error->message, $response->code); } return json_decode($response->body); }
public function setLastVisit($id = null) { $table = $this->getTable(); if (!$id) { $id = $this->id; } if ($id) { $date = new Date(); $table->store(array('id' => $id, 'lastvisitDate' => $date->__toString())); } return false; }
/** * Method to update data for an issue from GitHub * * @return boolean True on success * * @since 1.0 */ protected function updateData() { // Figure out the state based on the action $action = $this->hookData->action; $status = $this->processStatus($action); // Try to render the description with GitHub markdown $parsedText = $this->parseText($this->hookData->issue->body); // Prepare the dates for insertion to the database $dateFormat = $this->db->getDateFormat(); $modified = new Date($this->hookData->issue->updated_at); // Only update fields that may have changed, there's no API endpoint to show that so make some guesses $data = array(); $data['title'] = $this->hookData->issue->title; $data['description'] = $parsedText; $data['description_raw'] = $this->hookData->issue->body; if (!is_null($status)) { $data['status'] = $status; } $data['modified_date'] = $modified->format($dateFormat); $data['modified_by'] = $this->hookData->sender->login; // Add the closed date if the status is closed if ($this->hookData->issue->closed_at) { $closed = new Date($this->hookData->issue->closed_at); $data['closed_date'] = $closed->format($dateFormat); } // Process labels for the item $data['labels'] = $this->processLabels($this->hookData->issue->number); try { $table = new IssuesTable($this->db); $table->load(array('issue_number' => $this->hookData->issue->number, 'project_id' => $this->project->project_id)); $table->save($data); } catch (\Exception $e) { $this->logger->error(sprintf('Error updating GitHub issue %s/%s #%d in the tracker: %s', $this->project->gh_user, $this->project->gh_project, $this->hookData->issue->number, $e->getMessage())); $this->getContainer()->get('app')->close(); } $this->triggerEvent('onIssueAfterUpdate', $table); // Add a reopen record to the activity table if the status is closed if ($action == 'reopened') { $this->addActivityEvent('reopen', $this->hookData->issue->updated_at, $this->hookData->sender->login, $this->project->project_id, $this->hookData->issue->number); } // Add a close record to the activity table if the status is closed if ($this->hookData->issue->closed_at) { $this->addActivityEvent('close', $this->hookData->issue->closed_at, $this->hookData->sender->login, $this->project->project_id, $this->hookData->issue->number); } // Store was successful, update status $this->logger->info(sprintf('Updated GitHub issue %s/%s #%d to the tracker.', $this->project->gh_user, $this->project->gh_project, $this->hookData->issue->number)); return true; }
/** * Method to list issues. * * @param string $user The name of the owner of the GitHub repository. * @param string $repo The name of the GitHub repository. * @param string $milestone The milestone number, 'none', or *. * @param string $state The optional state to filter requests by. [open, closed] * @param string $assignee The assignee name, 'none', or *. * @param string $mentioned The GitHub user name. * @param string $labels The list of comma separated Label names. Example: bug,ui,@high. * @param string $sort The sort order: created, updated, comments, default: created. * @param string $direction The list direction: asc or desc, default: desc. * @param Date $since The date/time since when issues should be returned. * @param integer $page The page number from which to get items. * @param integer $limit The number of items on a page. * * @return object * * @since 1.0 * @throws \DomainException */ public function getListByRepository($user, $repo, $milestone = null, $state = null, $assignee = null, $mentioned = null, $labels = null, $sort = null, $direction = null, Date $since = null, $page = 0, $limit = 0) { // Build the request path. $path = '/repos/' . $user . '/' . $repo . '/issues'; $uri = new Uri($this->fetchUrl($path, $page, $limit)); if ($milestone) { $uri->setVar('milestone', $milestone); } if ($state) { $uri->setVar('state', $state); } if ($assignee) { $uri->setVar('assignee', $assignee); } if ($mentioned) { $uri->setVar('mentioned', $mentioned); } if ($labels) { $uri->setVar('labels', $labels); } if ($sort) { $uri->setVar('sort', $sort); } if ($direction) { $uri->setVar('direction', $direction); } if ($since) { $uri->setVar('since', $since->toISO8601()); } // Send the request. return $this->processResponse($this->client->get((string) $uri)); }
/** * Method to insert data for an issue from GitHub * * @return void * * @since 1.0 */ protected function insertIssue() { // Try to render the description with GitHub markdown $parsedText = $this->parseText($this->hookData->issue->body); // Prepare the dates for insertion to the database $dateFormat = $this->db->getDateFormat(); $opened = new Date($this->hookData->issue->created_at); $modified = new Date($this->hookData->issue->updated_at); $data = array(); $data['issue_number'] = $this->hookData->issue->number; $data['title'] = $this->hookData->issue->title; $data['description'] = $parsedText; $data['description_raw'] = $this->hookData->issue->body; $data['status'] = $this->hookData->issue->state == 'open' ? 1 : 10; $data['opened_date'] = $opened->format($dateFormat); $data['opened_by'] = $this->hookData->issue->user->login; $data['modified_date'] = $modified->format($dateFormat); $data['project_id'] = $this->project->project_id; $data['build'] = $this->hookData->repository->default_branch; // Add the closed date if the status is closed if ($this->hookData->issue->closed_at) { $closed = new Date($this->hookData->issue->closed_at); $data['closed_date'] = $closed->format($dateFormat); $data['closed_by'] = $this->hookData->sender->login; } // If the title has a [# in it, assume it's a JoomlaCode Tracker ID if (preg_match('/\\[#([0-9]+)\\]/', $this->hookData->issue->title, $matches)) { $data['foreign_number'] = $matches[1]; } elseif (preg_match('/tracker_item_id=([0-9]+)/', $this->hookData->issue->body, $matches)) { $data['foreign_number'] = $matches[1]; } // Process labels for the item $data['labels'] = $this->processLabels($this->hookData->issue->number); try { $table = new IssuesTable($this->db); $table->save($data); } catch (\Exception $e) { $this->logger->error(sprintf('Error adding GitHub issue %s/%s #%d to the tracker: %s', $this->project->gh_user, $this->project->gh_project, $this->hookData->issue->number, $e->getMessage())); $this->getContainer()->get('app')->close(); } $this->triggerEvent('onCommentAfterCreateIssue', $table); // Pull the user's avatar if it does not exist $this->pullUserAvatar($this->hookData->issue->user->login); // Add a close record to the activity table if the status is closed if ($this->hookData->issue->closed_at) { $this->addActivityEvent('close', $data['closed_date'], $this->hookData->sender->login, $this->project->project_id, $this->hookData->issue->number); } // Store was successful, update status $this->logger->info(sprintf('Added GitHub issue %s/%s #%d to the tracker.', $this->project->gh_user, $this->project->gh_project, $this->hookData->issue->number)); }
/** * Mark notifications as read in a repository. * * Marking all notifications in a repository as “read” removes them from the default view on GitHub.com. * * @param string $owner Repository owner. * @param string $repo Repository name. * @param boolean $unread Changes the unread status of the threads. * @param boolean $read Inverse of “unread”. * @param Date $last_read_at Describes the last point that notifications were checked. * Anything updated since this time will not be updated. Default: Now. Expected in ISO 8601 format. * * @return object * * @since 1.0 */ public function markReadRepository($owner, $repo, $unread, $read, Date $last_read_at = null) { // Build the request path. $path = '/repos/' . $owner . '/' . $repo . '/notifications'; $data = array('unread' => $unread, 'read' => $read); if ($last_read_at) { $data['last_read_at'] = $last_read_at->toISO8601(); } return $this->processResponse($this->client->put($this->fetchUrl($path), json_encode($data)), 205); }