public function apply($id) { jimport('joomla.client.github'); jimport('joomla.client.curl'); $table = JTable::getInstance('tests', 'PatchTesterTable'); $github = new JGithub(); $pull = $github->pulls->get($this->getState('github_user'), $this->getState('github_repo'), $id); if (is_null($pull->head->repo)) { throw new Exception(JText::_('COM_PATCHTESTER_REPO_IS_GONE')); } $patch = JCurl::getAdapter($pull->diff_url)->fetch()->body; $files = $this->parsePatch($patch); foreach ($files as $file) { if ($file->action == 'deleted' && !file_exists(JPATH_ROOT . '/' . $file->old)) { throw new Exception(sprintf(JText::_('COM_PATCHTESTER_FILE_DELETED_DOES_NOT_EXIST_S'), $file->old)); } if ($file->action == 'added' || $file->action == 'modified') { // if the backup file already exists, we can't apply the patch if (file_exists(JPATH_COMPONENT . '/backups/' . md5($file->new) . '.txt')) { throw new Exception(sprintf(JText::_('COM_PATCHTESTER_CONFLICT_S'), $file->new)); } if ($file->action == 'modified' && !file_exists(JPATH_ROOT . '/' . $file->old)) { throw new Exception(sprintf(JText::_('COM_PATCHTESTER_FILE_MODIFIED_DOES_NOT_EXIST_S'), $file->old)); } $url = 'https://raw.github.com/' . $pull->head->user->login . '/' . $pull->head->repo->name . '/' . $pull->head->ref . '/' . $file->new; $file->body = JCurl::getAdapter($url)->fetch()->body; } } // at this point, we have ensured that we have all the new files and there are no conflicts foreach ($files as $file) { // we only create a backup if the file already exists if ($file->action == 'deleted' || file_exists(JPATH_ROOT . '/' . $file->new) && $file->action == 'modified') { if (!JFile::copy(JPath::clean(JPATH_ROOT . '/' . $file->old), JPATH_COMPONENT . '/backups/' . md5($file->old) . '.txt')) { throw new Exception(sprintf('Can not copy file %s to %s', JPATH_ROOT . '/' . $file->old, JPATH_COMPONENT . '/backups/' . md5($file->old) . '.txt')); } } switch ($file->action) { case 'modified': case 'added': if (!JFile::write(JPath::clean(JPATH_ROOT . '/' . $file->new), $file->body)) { throw new Exception(sprintf('Can not write the file: %s', JPATH_ROOT . '/' . $file->new)); } break; case 'deleted': if (!JFile::delete(JPATH::clean(JPATH_ROOT . '/' . $file->old))) { throw new Exception(sprintf('Can not delete the file: %s', JPATH_ROOT . '/' . $file->old)); } break; } } $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(); if (!$table->store()) { throw new Exception($table->getError()); } return true; }
public function sendRequest($url, $method = 'get', $data = array(), $options = array()) { $curl_options = array(CURLOPT_HEADER => false, CURLOPT_FOLLOWLOCATION => false, CURLOPT_USERAGENT => 'JGithub', CURLOPT_CONNECTTIMEOUT => 120, CURLINFO_HEADER_OUT => true, CURLOPT_HTTPHEADER => array('Content-type: application/json'), CURLOPT_CAINFO => dirname(__FILE__) . '/github/cacert.pem', CURLOPT_SSL_VERIFYPEER => true, CURLOPT_SSL_VERIFYHOST => 2); 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; } $curlResponse = JCurl::getAdapter('https://api.github.com' . $url)->setOptions($curl_options)->fetch(); $response = new JHttpResponse(); $response->code = $curlResponse->http_code; $response->headers = $curlResponse->request_header; $response->body = json_decode($curlResponse->body); return $response; }