commit 077e57ccfafe15b069da2d9fd1afa926330903d2 Author: Ian MacLennan Date: Tue Oct 11 09:02:57 2011 -0400 Creating component diff --git a/administrator/components/com_patchtester/access.xml b/administrator/components/com_patchtester/access.xml new file mode 100644 index 0000000..fdd2e4c --- /dev/null +++ b/administrator/components/com_patchtester/access.xml @@ -0,0 +1,7 @@ + + +
+ + +
+
diff --git a/administrator/components/com_patchtester/backups/index.html b/administrator/components/com_patchtester/backups/index.html new file mode 100644 index 0000000..e69de29 diff --git a/administrator/components/com_patchtester/config.xml b/administrator/components/com_patchtester/config.xml new file mode 100644 index 0000000..e63f0ff --- /dev/null +++ b/administrator/components/com_patchtester/config.xml @@ -0,0 +1,34 @@ + + +
+ + + + + +
+ +
+ + +
+
diff --git a/administrator/components/com_patchtester/controller.php b/administrator/components/com_patchtester/controller.php new file mode 100644 index 0000000..42963ae --- /dev/null +++ b/administrator/components/com_patchtester/controller.php @@ -0,0 +1,35 @@ +getModel('pull'); + if ($model->apply(JRequest::getVar('pull_id'))) { + $msg = 'Patch successfully applied'; + } else { + $msg = 'Patch did not apply'; + } + $this->setRedirect(JRoute::_('index.php?option=com_patchtester&view=pulls', false), $msg); + } + + public function revert() + { + $model = $this->getModel('pull'); + if ($model->revert(JRequest::getVar('pull_id'))) { + $msg = 'Patch successfully reverted'; + } else { + $msg = 'Patch did not revert'; + } + $this->setRedirect(JRoute::_('index.php?option=com_patchtester&view=pulls', false), $msg); + } + +} diff --git a/administrator/components/com_patchtester/index.html b/administrator/components/com_patchtester/index.html new file mode 100644 index 0000000..e69de29 diff --git a/administrator/components/com_patchtester/language/en-GB/en-GB.com_patchtester.ini b/administrator/components/com_patchtester/language/en-GB/en-GB.com_patchtester.ini new file mode 100644 index 0000000..7791b2e --- /dev/null +++ b/administrator/components/com_patchtester/language/en-GB/en-GB.com_patchtester.ini @@ -0,0 +1,13 @@ +COM_PATCHTESTER_NOT_APPLIED="Not Applied" +COM_PATCHTESTER_APPLIED="Applied" +COM_PATCHTESTER_REVERT_PATCH="Revert Patch" +COM_PATCHTESTER_APPLY_PATCH="Apply Patch" +COM_PATCHTESTER_TEST_THIS_PATCH="Test This Patch" +COM_PATCHTESTER_REPO_IS_GONE="The patch could not be applied because the repository is missing" +COM_PATCHTESTER_CONFLICT="The patch could not be applied because it conflicts with a previously applied patch" +COM_PATCHTESTER_COMPONENT_LABEL="Patch Tester" +COM_PATCHTESTER_COMPONENT_DESC="Patch Tester Configuration Values" +COM_PATCHTESTER_FIELD_ORG_DESC="Github Username" +COM_PATCHTESTER_FIELD_ORG_LABEL="Name of account on Github of which to monitor pull requests" +COM_PATCHTESTER_FIELD_REPO_DESC="Github Repository" +COM_PATCHTESTER_FIELD_REPO_LABEL="Name of repository on Github of which to monitor pull requests" diff --git a/administrator/components/com_patchtester/language/en-GB/en-GB.com_patchtester.sys.ini b/administrator/components/com_patchtester/language/en-GB/en-GB.com_patchtester.sys.ini new file mode 100644 index 0000000..d7f8009 --- /dev/null +++ b/administrator/components/com_patchtester/language/en-GB/en-GB.com_patchtester.sys.ini @@ -0,0 +1,3 @@ +COM_PATCHTESTER="Patch Tester" +COM_PATCHTESTER_XML_DESCRIPTION="Component for pull request management testing" + diff --git a/administrator/components/com_patchtester/language/en-GB/index.html b/administrator/components/com_patchtester/language/en-GB/index.html new file mode 100644 index 0000000..e69de29 diff --git a/administrator/components/com_patchtester/language/index.html b/administrator/components/com_patchtester/language/index.html new file mode 100644 index 0000000..e69de29 diff --git a/administrator/components/com_patchtester/models/index.html b/administrator/components/com_patchtester/models/index.html new file mode 100644 index 0000000..e69de29 diff --git a/administrator/components/com_patchtester/models/pull.php b/administrator/components/com_patchtester/models/pull.php new file mode 100644 index 0000000..4666a1c --- /dev/null +++ b/administrator/components/com_patchtester/models/pull.php @@ -0,0 +1,133 @@ +setState('params', $params); + $this->setState('github_user', $params->get('org')); + $this->setState('github_repo', $params->get('repo')); + + parent::populateState(); + } + + + public function apply($id) + { + jimport('joomla.client.github'); + jimport('joomla.client.http'); + + $table = JTable::getInstance('tests', 'PatchTesterTable'); + $github = new JGithub(); + $pull = $github->pulls->get($this->getState('github_user'), $this->getState('github_repo'), $id); + $patchUrl = $pull->patch_url; + + $http = new JHttp; + + $patch = $http->get($patchUrl)->body; + $patch = explode("\n", $patch); + + $files = array(); + + foreach ($patch AS $line) + { + if (is_null($pull->head->repo)) { + $this->setError(JText::_('COM_PATCHTESTER_REPO_IS_GONE')); + return false; + } + + if (strpos($line, '--- a/') === 0) { + $file = substr($line, 6); + + // if the backup file already exists, we can't apply the patch + if (file_exists(JPATH_COMPONENT . '/backups/' . md5($file) . '.txt')) { + $this->setError(JText::_('COM_PATCHTESTER_CONFLICT')); + return false; + } + $files[] = $file; + } + } + + foreach ($files AS $file) + { + // we only create a backup if the file already exists + if (file_exists(JPATH_ROOT . '/' . $file)) { + JFile::copy(JPath::clean(JPATH_ROOT . '/' . $file), JPATH_COMPONENT . '/backups/' . md5($file) . '.txt'); + } + + $url = 'https://raw.github.com/' . $pull->head->user->login . '/' . $pull->head->repo->name . '/' . + $pull->head->ref . $file; + $newFile = $http->get($url); + JFile::write(JPath::clean(JPATH_ROOT . '/' . $file), $newFile->body); + + } + $table->pull_id = $pull->number; + $table->data = json_encode($files); + $table->patched_by = JFactory::getUser()->id; + $table->applied = 1; + $version = new JVersion; + $table->applied_version = $version->getShortVersion(); + $result = $table->store(); + + if ($result) { + return true; + } else { + return false; + } + } + + public function revert($id) + { + $table = JTable::getInstance('tests', 'PatchTesterTable'); + + $table->load($id); + + // we don't want to restore files from an older version + $version = new JVersion; + if ($table->applied_version != $version->getShortVersion()) { + $table->applied = 0; + $table->applied_version = ''; + $table->store(); + return true; + } + + $files = json_decode($table->data); + + foreach ($files AS $file) { + JFile::copy(JPATH_COMPONENT . '/backups/' . md5($file) . '.txt', JPATH_ROOT . '/' . $file); + JFile::delete(JPATH_COMPONENT . '/backups/' . md5($file) . '.txt'); + } + + $table->applied_version = ''; + $table->applied = 0; + $table->store(); + + return true; + } + +} diff --git a/administrator/components/com_patchtester/models/pulls.php b/administrator/components/com_patchtester/models/pulls.php new file mode 100644 index 0000000..4d25275 --- /dev/null +++ b/administrator/components/com_patchtester/models/pulls.php @@ -0,0 +1,110 @@ +setState('params', $params); + $this->setState('github_user', $params->get('org')); + $this->setState('github_repo', $params->get('repo')); + // List state information. + parent::populateState('title', 'asc'); + } + + /** + * Method to get a store id based on model configuration state. + * + * This is necessary because the model is used by the component and + * different modules that might need different sets of data or different + * ordering requirements. + * + * @param string $id A prefix for the store id. + * @return string A store id. + * @since 1.6 + */ + protected function getStoreId($id = '') + { + return parent::getStoreId($id); + } + + public function getAppliedPatches() + { + $query = $this->_db->getQuery(true); + $query->select('*'); + $query->from('#__tests'); + $query->where('applied = 1'); + + $this->_db->setQuery($query); + $tests = $this->_db->loadObjectList('pull_id'); + return $tests; + } + + public function getItems() + { + jimport('joomla.client.github'); + + if ($this->getState('github_user') == '' || $this->getState('github_repo') == '') { + return array(); + } + + $github = new JGithub(); + $pulls = $github->pulls->getAll($this->getState('github_user'), $this->getState('github_repo')); + usort($pulls, array($this, 'sortItems')); + return $pulls; + } + + public function sortItems($a, $b) + { + return strcasecmp($a->title, $b->title); + } +} diff --git a/administrator/components/com_patchtester/patchtester.php b/administrator/components/com_patchtester/patchtester.php new file mode 100644 index 0000000..c8a73a3 --- /dev/null +++ b/administrator/components/com_patchtester/patchtester.php @@ -0,0 +1,22 @@ +authorise('core.manage', 'com_patchtester')) { + return JError::raiseWarning(404, JText::_('JERROR_ALERTNOAUTHOR')); +} + +// Include dependencies +jimport('joomla.application.component.controller'); + +$controller = JController::getInstance('PatchTester'); +$controller->execute(JRequest::getCmd('task')); +$controller->redirect(); diff --git a/administrator/components/com_patchtester/patchtester.xml b/administrator/components/com_patchtester/patchtester.xml new file mode 100644 index 0000000..1ae58f8 --- /dev/null +++ b/administrator/components/com_patchtester/patchtester.xml @@ -0,0 +1,46 @@ + + + com_patchtester + Ian MacLennan + October 2011 + (C) 2011 Ian MacLennan. All rights reserved. + + GNU General Public License version 2 or later; see + LICENSE.txt + ianlenmac@gmail.com + http://github.com/ianmacl + 1.0alpha + COM_PATCHTESTER_XML_DESCRIPTION + + + + sql/install.mysql.utf8.sql + + + + + sql/uninstall.mysql.utf8.sql + + + + + patchtester.php + + + language/en-GB.com_patchtester.ini + + + com_patchtester + + access.xml + config.xml + controller.php + patchtester.php + controllers models + sql + tables + views + language + + + diff --git a/administrator/components/com_patchtester/sql/index.html b/administrator/components/com_patchtester/sql/index.html new file mode 100644 index 0000000..e69de29 diff --git a/administrator/components/com_patchtester/sql/install.mysql.utf8.sql b/administrator/components/com_patchtester/sql/install.mysql.utf8.sql new file mode 100644 index 0000000..6666174 --- /dev/null +++ b/administrator/components/com_patchtester/sql/install.mysql.utf8.sql @@ -0,0 +1,11 @@ +CREATE TABLE IF NOT EXISTS `#__tests` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `pull_id` int(11) NOT NULL, + `data` varchar(5000) NOT NULL, + `patched_by` int(11) NOT NULL, + `applied` int(11) NOT NULL, + `applied_version` varchar(25) NOT NULL, + `rating` int(11) NOT NULL, + `comments` varchar(3000) NOT NULL, + PRIMARY KEY (`id`) +) DEFAULT CHARSET=utf8; diff --git a/administrator/components/com_patchtester/sql/uninstall.mysql.utf8.sql b/administrator/components/com_patchtester/sql/uninstall.mysql.utf8.sql new file mode 100644 index 0000000..1216e3a --- /dev/null +++ b/administrator/components/com_patchtester/sql/uninstall.mysql.utf8.sql @@ -0,0 +1 @@ +DROP TABLE IF NOT EXISTS `#__tests` diff --git a/administrator/components/com_patchtester/tables/index.html b/administrator/components/com_patchtester/tables/index.html new file mode 100644 index 0000000..e69de29 diff --git a/administrator/components/com_patchtester/tables/tests.php b/administrator/components/com_patchtester/tables/tests.php new file mode 100644 index 0000000..9cac601 --- /dev/null +++ b/administrator/components/com_patchtester/tables/tests.php @@ -0,0 +1,27 @@ + + + +
+ + + + + + + + + + + + + + + + + items as $i => $item) : + if (isset($this->patches[$item->number])) { + $patch = $this->patches[$item->number]; + } else { + $patch = false; + } + ?> + + + + + + + + +
+ + + + + + + +
+
+ id); ?> + + title; ?> + + applied) { + echo JText::_('COM_PATCHTESTER_APPLIED'); + } else { + echo JText::_('COM_PATCHTESTER_NOT_APPLIED'); + } + ?> + + applied) { + echo ''.JText::_('COM_PATCHTESTER_REVERT_PATCH').''; + } else { + echo ''.JText::_('COM_PATCHTESTER_APPLY_PATCH').''; + } + ?> +
+ +
+ + + + +
+
diff --git a/administrator/components/com_patchtester/views/pulls/tmpl/index.html b/administrator/components/com_patchtester/views/pulls/tmpl/index.html new file mode 100644 index 0000000..e69de29 diff --git a/administrator/components/com_patchtester/views/pulls/view.html.php b/administrator/components/com_patchtester/views/pulls/view.html.php new file mode 100644 index 0000000..fde2531 --- /dev/null +++ b/administrator/components/com_patchtester/views/pulls/view.html.php @@ -0,0 +1,50 @@ +state = $this->get('State'); + $this->items = $this->get('Items'); + $this->patches = $this->get('AppliedPatches'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) { + JError::raiseError(500, implode("\n", $errors)); + return false; + } + + $this->addToolbar(); + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + */ + protected function addToolbar() + { + JToolBarHelper::title('Joomla! Patch Tester'); + JToolBarHelper::preferences('com_patchtester'); + } +} diff --git a/components/com_patchtester/index.html b/components/com_patchtester/index.html new file mode 100644 index 0000000..e69de29 diff --git a/components/com_patchtester/patchtester.php b/components/com_patchtester/patchtester.php new file mode 100644 index 0000000..e69de29 diff --git a/libraries/joomla/client/github.php b/libraries/joomla/client/github.php new file mode 100755 index 0000000..e4d76ca --- /dev/null +++ b/libraries/joomla/client/github.php @@ -0,0 +1,177 @@ +credentials['username'] = $options['username']; + $this->credentials['password'] = $options['password']; + $this->authentication_method = JGithub::AUTHENTICATION_BASIC; + } elseif (isset($options['token'])) { + $this->credentials['token'] = $options['token']; + $this->authentication_method = JGithub::AUTHENTICATION_OAUTH; + } else { + $this->authentication_method = JGithub::AUTHENTICATION_NONE; + } + + $this->http = curl_init(); + } + + public function __get($name) + { + if ($name == 'gists') { + if ($this->gists == null) { + $this->gists = new JGithubGists($this); + } + return $this->gists; + } + + if ($name == 'issues') { + if ($this->issues == null) { + $this->issues = new JGithubIssues($this); + } + return $this->issues; + } + + if ($name == 'pulls') { + if ($this->pulls == null) { + $this->pulls = new JGithubPulls($this); + } + return $this->pulls; + } + + } + + public function sendRequest($url, $method = 'get', $data = array(), $options = array()) + { + + $this->http = curl_init(); + + $curl_options = array( + CURLOPT_URL => 'https://api.github.com'.$url, + CURLOPT_RETURNTRANSFER => true, + CURLOPT_HEADER => false, + CURLOPT_FOLLOWLOCATION => false, + CURLOPT_USERAGENT => 'JGithub', + CURLOPT_CONNECTTIMEOUT => 120, + CURLOPT_TIMEOUT => 120, + CURLINFO_HEADER_OUT => true, + CURLOPT_HTTPHEADER => array('Content-type: application/json') + ); + + switch ($this->authentication_method) + { + case JGithub::AUTHENTICATION_BASIC: + $curl_options[CURLOPT_USERPWD] = $this->credentials['username'].':'.$this->credentials['password']; + break; + + case JGithub::AUTHENTICATION_OAUTH: + if (strpos($url, '?') === false) { + $url .= '?access_token='.$this->credentials['token']; + } else { + $url .= '&access_token='.$this->credentials['token']; + } + break; + } + + + switch ($method) { + case 'post': + $curl_options[CURLOPT_POST] = 1; + $curl_options[CURLOPT_POSTFIELDS] = json_encode($data); + break; + + case 'put': + $curl_options[CURLOPT_POST] = 1; + $curl_options[CURLOPT_POSTFIELDS] = ''; + $curl_options[CURLOPT_CUSTOMREQUEST] = 'PUT'; + $curl_options[CURLOPT_HTTPGET] = false; + break; + + case 'patch': + $curl_options[CURLOPT_POSTFIELDS] = json_encode($data); + case 'delete': + $curl_options[CURLOPT_CUSTOMREQUEST] = strtoupper($method); + $curl_options[CURLOPT_POST] = false; + $curl_options[CURLOPT_HTTPGET] = false; + + break; + + case 'get': + $curl_options[CURLOPT_POSTFIELDS] = null; + $curl_options[CURLOPT_POST] = false; + $curl_options[CURLOPT_HTTPGET] = true; + + break; + } + + curl_setopt_array($this->http, $curl_options); + + $response = new JHttpResponse; + $response->body = json_decode(curl_exec($this->http)); + + $request_data = curl_getinfo($this->http); + $response->headers = $request_data['request_header']; + $response->code = $request_data['http_code']; + + curl_close($this->http); + + return $response; + } +} diff --git a/libraries/joomla/client/github/githubgists.php b/libraries/joomla/client/github/githubgists.php new file mode 100644 index 0000000..d49deb9 --- /dev/null +++ b/libraries/joomla/client/github/githubgists.php @@ -0,0 +1,182 @@ +connector = $connector; + } + + protected function paginate($url, $page = 0, $per_page = 0) + { + //TODO: Make a new base class and move paginate into it + $query_string = array(); + + if ($page > 0) { + $query_string[] = 'page='.(int)$page; + } + + if ($per_page > 0) { + $query_string[] = 'per_page='.(int)$per_page; + } + + if (isset($query_string[0])) { + $query = implode('&', $query_string); + } else { + $query = ''; + } + + if (strlen($query) > 0) { + if (strpos($url, '?') === false) { + $url .= '?'.$query; + } else { + $url .= '&'.$query; + } + } + + return $url; + } + + public function getAll($page = 0, $per_page = 0) + { + $url = '/gists'; + return $this->connector->sendRequest($this->paginate($url, $page, $per_page))->body; + } + + public function getByUser($user, $page = 0, $per_page = 0) + { + $url = '/users/'.$user.'/gists'; + return $this->connector->sendRequest($this->paginate($url, $page, $per_page))->body; + } + + public function getPublic($page = 0, $per_page = 0) + { + $url = '/gists/public'; + return $this->connector->sendRequest($this->paginate($url, $page, $per_page))->body; + } + + public function getStarred($page = 0, $per_page = 0) + { + $url = '/gists/starred'; + return $this->connector->sendRequest($this->paginate($url, $page, $per_page))->body; + } + + public function get($gist_id) + { + return $this->connector->sendRequest('/gists/'.(int)$gist_id)->body; + } + + public function create($files, $public = false, $description = null) + { + $gist = new stdClass; + $gist->public = $public; + $gist->files = $files; + + if (!empty($description)) { + $gist->description = $description; + } + + return $this->connector->sendRequest('/gists', 'post', $gist)->body; + } + + public function edit($gist_id, $files, $description = null) + { + $gist = new stdClass; + $gist->files = $files; + + if (!empty($description)) { + $gist->description = $description; + } + + return $this->connector->sendRequest('/gists/'.(int)$gist_id, 'patch', $gist)->body; + } + + public function star($gist_id) + { + return $this->connector->sendRequest('/gists/'.(int)$gist_id.'/star', 'put')->body; + } + + public function unstar($gist_id) + { + return $this->connector->sendRequest('/gists/'.(int)$gist_id.'/star', 'delete')->body; + } + + public function isStarred($gist_id) + { + $response = $this->connector->sendRequest('/gists/'.(int)$gist_id.'/star'); + + if ($response->code == '204') { + return true; + } else { // the code should be 404 + return false; + } + } + + public function fork($gist_id) + { + return $this->connector->sendRequest('/gists/'.(int)$gist_id.'/fork', 'put')->body; + } + + public function delete($gist_id) + { + return $this->connector->sendRequest('/gists/'.(int)$gist_id, 'delete')->body; + } + + public function getComments($gist_id) + { + return $this->connector->sendRequest('/gists/'.(int)$gist_id.'/comments')->body; + } + + public function getComment($comment_id) + { + return $this->connector->sendRequest('/gists/comments/'.(int)$comment_id)->body; + } + + public function createComment($gist_id, $comment) + { + return $this->connector->sendRequest('/gists/'.(int)$gist_id.'/comments', 'post', array('body' => $comment))->body; + } + + public function editComment($comment_id, $comment) + { + return $this->connector->sendRequest('/gists/comments/'.(int)$comment_id, 'patch', array('body' => $comment))->body; + } + + public function deleteComment($comment_id) + { + return $this->connector->sendRequest('/gists/comments/'.(int)$comment_id, 'delete')->body; + } +} diff --git a/libraries/joomla/client/github/githubissues.php b/libraries/joomla/client/github/githubissues.php new file mode 100644 index 0000000..06c3f3a --- /dev/null +++ b/libraries/joomla/client/github/githubissues.php @@ -0,0 +1,190 @@ +connector = $connector; + } + + protected function paginate($url, $page = 0, $per_page = 0) + { + //TODO: Make a new base class and move paginate into it + $query_string = array(); + + if ($page > 0) { + $query_string[] = 'page='.(int)$page; + } + + if ($per_page > 0) { + $query_string[] = 'per_page='.(int)$per_page; + } + + if (isset($query_string[0])) { + $query = implode('&', $query_string); + } else { + $query = ''; + } + + if (strlen($query) > 0) { + if (strpos($url, '?') === false) { + $url .= '?'.$query; + } else { + $url .= '&'.$query; + } + } + + return $url; + } + + public function getAll($parameters = array(), $page = 0, $per_page = 0) + { + $url = '/issues'; + + $queryString = ''; + + foreach ($parameters AS $parameter) { + $queryString .= ''; + } + if (isset($options['filter'])) { + } + return $this->connector->sendRequest($this->paginate($url, $page, $per_page))->body; + } + + public function getByUser($user, $page = 0, $per_page = 0) + { + $url = '/users/'.$user.'/gists'; + return $this->connector->sendRequest($this->paginate($url, $page, $per_page))->body; + } + + public function getPublic($page = 0, $per_page = 0) + { + $url = '/gists/public'; + return $this->connector->sendRequest($this->paginate($url, $page, $per_page))->body; + } + + public function getStarred($page = 0, $per_page = 0) + { + $url = '/gists/starred'; + return $this->connector->sendRequest($this->paginate($url, $page, $per_page))->body; + } + + public function get($gist_id) + { + return $this->connector->sendRequest('/gists/'.(int)$gist_id)->body; + } + + public function create($files, $public = false, $description = null) + { + $gist = new stdClass; + $gist->public = $public; + $gist->files = $files; + + if (!empty($description)) { + $gist->description = $description; + } + + return $this->connector->sendRequest('/gists', 'post', $gist)->body; + } + + public function edit($gist_id, $files, $description = null) + { + $gist = new stdClass; + $gist->files = $files; + + if (!empty($description)) { + $gist->description = $description; + } + + return $this->connector->sendRequest('/gists/'.(int)$gist_id, 'patch', $gist)->body; + } + + public function star($gist_id) + { + return $this->connector->sendRequest('/gists/'.(int)$gist_id.'/star', 'put')->body; + } + + public function unstar($gist_id) + { + return $this->connector->sendRequest('/gists/'.(int)$gist_id.'/star', 'delete')->body; + } + + public function isStarred($gist_id) + { + $response = $this->connector->sendRequest('/gists/'.(int)$gist_id.'/star'); + + if ($response->code == '204') { + return true; + } else { // the code should be 404 + return false; + } + } + + public function fork($gist_id) + { + return $this->connector->sendRequest('/gists/'.(int)$gist_id.'/fork', 'put')->body; + } + + public function delete($gist_id) + { + return $this->connector->sendRequest('/gists/'.(int)$gist_id, 'delete')->body; + } + + public function getComments($gist_id) + { + return $this->connector->sendRequest('/gists/'.(int)$gist_id.'/comments')->body; + } + + public function getComment($comment_id) + { + return $this->connector->sendRequest('/gists/comments/'.(int)$comment_id)->body; + } + + public function createComment($gist_id, $comment) + { + return $this->connector->sendRequest('/gists/'.(int)$gist_id.'/comments', 'post', array('body' => $comment))->body; + } + + public function editComment($comment_id, $comment) + { + return $this->connector->sendRequest('/gists/comments/'.(int)$comment_id, 'patch', array('body' => $comment))->body; + } + + public function deleteComment($comment_id) + { + return $this->connector->sendRequest('/gists/comments/'.(int)$comment_id, 'delete')->body; + } +} diff --git a/libraries/joomla/client/github/githubpulls.php b/libraries/joomla/client/github/githubpulls.php new file mode 100644 index 0000000..6ba0aae --- /dev/null +++ b/libraries/joomla/client/github/githubpulls.php @@ -0,0 +1,144 @@ +connector->sendRequest($this->paginate($url, $page, $per_page))->body; + } + + public function get($user, $repo, $pull_id) + { + return $this->connector->sendRequest('/repos/'.$user.'/'.$repo.'/pulls/'.(int)$pull_id)->body; + } + + public function create($user, $repo, $title, $base, $head, $body = '') + { + $pull = new stdClass; + $pull->title = $title; + $pull->base = $base; + $pull->head = $head; + $pull->body = $body; + + return $this->connector->sendRequest('/repos/'.$user.'/'.$repo.'/pulls', 'post', $pull)->body; + } + + public function createFromIssue($user, $repo, $issue, $base, $head) + { + $pull = new stdClass; + $pull->issue = (int)$issue; + $pull->base = $base; + $pull->head = $head; + + return $this->connector->sendRequest('/repos/'.$user.'/'.$repo.'/pulls', 'post', $pull)->body; + } + + public function edit($user, $repo, $id, $title = null, $body = null, $state = null) + { + $pull = new stdClass; + + if (isset($title)) { + $pull->title = $title; + } + + if (isset($body)) { + $pull->body = $body; + } + + if (isset($state)) { + $pull->state = $state; + } + + return $this->connector->sendRequest('/repos/'.$user.'/'.$repo.'/pulls/'.(int)$id, 'patch', $pull)->body; + } + + public function getCommits($user, $repo, $pull_id, $page = 0, $per_page = 0) + { + $url = '/repos/'.$user.'/'.$repo.'/pulls/'.(int)$pull_id.'/commits'; + return $this->connector->sendRequest($this->paginate($url, $page, $per_page))->body; + } + + public function getFiles($user, $repo, $pull_id, $page = 0, $per_page = 0) + { + $url = '/repos/'.$user.'/'.$repo.'/pulls/'.(int)$pull_id.'/files'; + return $this->connector->sendRequest($this->paginate($url, $page, $per_page))->body; + } + + public function isMerged($user, $repo, $pull_id) + { + $url = '/repos/'.$user.'/'.$repo.'/pulls/'.(int)$pull_id.'/merge'; + $response = $this->connector->sendRequest($url); + + if ($response->code == '204') { + return true; + } else { // the code should be 404 + return false; + } + } + + public function merge($user, $repo, $pull_id, $commit_message = '') + { + return $this->connector->sendRequest('/repos/'.$user.'/'.$repo.'/pulls/'.(int)$pull_id.'/merge', 'put', array('commit_message' => $commit_message))->body; + } + + public function getComments($user, $repo, $pull_id, $page = 0, $per_page = 0) + { + $url = '/repos/'.$user.'/'.$repo.'/pulls/'.(int)$pull_id.'/comments'; + return $this->connector->sendRequest($this->paginate($url, $page, $per_page))->body; + } + + public function getComment($user, $repo, $comment_id) + { + return $this->connector->sendRequest('/repos/'.$user.'/'.$repo.'/pulls/comments/'.(int)$comment_id)->body; + } + + public function createComment($user, $repo, $pull_id, $body, $commit_id, $path, $position) + { + $comment = new stdClass; + $comment->body = $body; + $comment->commit_id = $commit_id; + $comment->path = $path; + $comment->position = $position; + + return $this->connector->sendRequest('/repos/'.$user.'/'.$repo.'/pulls/'.(int)$pull_id.'/comments', 'post', $comment)->body; + } + + public function createCommentReply($user, $repo, $pull_id, $body, $in_reply_to) + { + $comment = new stdClass; + $comment->body = $body; + $comment->in_reply_to = (int)$in_reply_to; + + return $this->connector->sendRequest('/repos/'.$user.'/'.$repo.'/pulls/'.(int)$pull_id.'/comments', 'post', $comment)->body; + } + + public function editComment($user, $repo, $comment_id, $body) + { + return $this->connector->sendRequest('/repos/'.$user.'/'.$repo.'/pulls/comments/'.(int)$comment_id, 'patch', array('body' => $body))->body; + } + + public function deleteComment($user, $repo, $comment_id) + { + return $this->connector->sendRequest('/repos/'.$user.'/'.$repo.'/pulls/comments/'.(int)$comment_id, 'delete')->body; + } + +} diff --git a/libraries/joomla/client/githubobject.php b/libraries/joomla/client/githubobject.php new file mode 100755 index 0000000..473450d --- /dev/null +++ b/libraries/joomla/client/githubobject.php @@ -0,0 +1,72 @@ +connector = $connector; + } + + protected function paginate($url, $page = 0, $per_page = 0) + { + //TODO: Make a new base class and move paginate into it + $query_string = array(); + + if ($page > 0) { + $query_string[] = 'page='.(int)$page; + } + + if ($per_page > 0) { + $query_string[] = 'per_page='.(int)$per_page; + } + + if (isset($query_string[0])) { + $query = implode('&', $query_string); + } else { + $query = ''; + } + + if (strlen($query) > 0) { + if (strpos($url, '?') === false) { + $url .= '?'.$query; + } else { + $url .= '&'.$query; + } + } + + return $url; + } +}