Я пытаюсь создать проблему в JIRA из моей инфраструктуры PHP YII2. Я пытаюсь сделать это - всякий раз, когда я создаю новую версию в своей системе, я хочу, чтобы проблема JIRA была создана автоматически для этой версии. Я нашел примеры в CURL, но пока это не работает. Я даже не получаю сообщение об ошибке. Он создает новую версию в моей системе, но ничего не происходит в JIRA, похоже, что она даже не пытается подключиться к JIRA.Создание проблемы в JIRA с использованием REST API - PHP YII2
Это мой VersionController.php -
<?php
namespace app\controllers;
require_once("Curl.php");
use Yii;
use app\models\Version;
use app\models\VersionSearch;
use app\models\Binfile;
use app\models\VersionStatus;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
use yii\swiftmailer\Mailer;
use yii\web\UnauthorizedHttpException;
use linslin\yii2\curl;
use understeam\yii2\httpclient;
use understeam\yii2\jira;
/**
* VersionController implements the CRUD actions for Version model.
*/
class VersionController extends Controller
{
public function behaviors()
{
return [
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'delete' => ['post'],
],
],
'access' => [
'class' => \yii\filters\AccessControl::className(),
'only' => ['index','create','update','view'],
'rules' => [
// allow authenticated users
[
'allow' => true,
'roles' => ['@'],
],
// everything else is denied
],
],
];
}
/**
* Lists all Version models.
* @return mixed
*/
public function actionIndex()
{
if (\Yii::$app->user->can('deleteVersion')) {
$template = '{view} {update} {delete} ';
}
else if((\Yii::$app->user->can('changeStatus')) || (\Yii::$app->user->can('uploadVersion'))){
$template = '{view} {update}';
}
else{$template = '{view}';
}
$searchModel = new VersionSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
'template' => $template,
]);
}
/**
* Displays a single Version model.
* @param integer $id
* @return mixed
*/
public function actionView($id)
{
return $this->render('view', [
'model' => $this->findModel($id),
]);
}
/**
* Creates a new Version model.
* If creation is successful, the browser will be redirected to the 'view' page.
* @return mixed
*/
public function actionCreate()
{
if(!\Yii::$app->user->can('createVersion')){
throw new UnauthorizedHttpException("Access denied: You don't have permission to create a version");
}else{
$model = new Version();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
//$this->actionSend();
$this->actionPostExample();
// $this->actionGetExample();
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('create', [
'model' => $model,
]);
}
}
}
/**
* Updates an existing Version model.
* If update is successful, the browser will be redirected to the 'view' page.
* @param integer $id
* @return mixed
*/
public function actionUpdate($id)
{
$model = $this->findModel($id);
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('update', [
'model' => $model,
]);
}
}
/**
* Deletes an existing Version model.
* If deletion is successful, the browser will be redirected to the 'index' page.
* @param integer $id
* @return mixed
*/
public function actionDelete($id)
{
if(!\Yii::$app->user->can('isAdmin')){
throw new UnauthorizedHttpException("Access denied: Only Admin can perform this action!!!");
}else{
$this->findModel($id)->delete();
return $this->redirect(['index']);
}
}
/**
* Finds the Version model based on its primary key value.
* If the model is not found, a 404 HTTP exception will be thrown.
* @param integer $id
* @return Version the loaded model
* @throws NotFoundHttpException if the model cannot be found
*/
protected function findModel($id)
{
if (($model = Version::findOne($id)) !== null) {
return $model;
} else {
throw new NotFoundHttpException('The requested page does not exist.');
}
}
public function actionSend()
{
Yii::$app->mailer->compose()
->setFrom('[email protected]')
->setTo('[email protected]')
->setSubject('Message test')
->setTextBody('Plain text content')
->setHtmlBody('<b>test</b>')
->send();
}
public function actionPostExample()
{
define('JIRA_URL', 'http://jiratest.../');
define('USERNAME', 'jenya');
define('PASSWORD', 'password');
function post_to($resource, $data)
{
$jdata = json_encode($data);
$ch = curl_init();
curl_setopt_array($ch, array(
CURLOPT_POST => 1,
CURLOPT_URL => JIRA_URL . '/rest/api/latest/' . $resource,
CURLOPT_USERPWD => USERNAME . ':' . PASSWORD,
CURLOPT_POSTFIELDS => $jdata,
CURLOPT_HTTPHEADER => array('Content-type: application/json'),
CURLOPT_RETURNTRANSFER => true
));
$result = curl_exec($ch);
curl_close($ch);
return json_decode($result);
}
$new_issue = array(
'fields' => array(
'project' => array('key' => 'key'),
'issuetype' => array('name' => 'Version Integration Task'),
'summary' => 'Test via REST',
'components' => 'General',
'customfield_10110' => 'name of value',
'fixVersions' => 'name of version',
'Description' => 'Description of issue goes here.',
//'labels' => array('a','b')
)
);
function create_issue($issue)
{
return post_to('issue', $issue);
}
$result = create_issue($new_issue);
if (property_exists($this, 'errors'))
{
echo "Error(s) creating issue:\n";
var_dump($result);
}
else
{
echo "New issue created at " . JIRA_URL ."/browse/{$result}\n";
}
}
}
Curl.php-
<?php
/**
* Yii2 cURL wrapper
* With RESTful support.
*
* @category Web-yii2
* @package yii2-curl
* @author Nils Gajsek <[email protected]>
* @copyright 2013-2015 Nils Gajsek<[email protected]>
* @license http://opensource.org/licenses/MIT MIT Public
* @version 1.0.7
* @link http://www.linslin.org
*
*/
namespace linslin\yii2\curl;
use Yii;
use yii\base\Exception;
use yii\helpers\Json;
use yii\web\HttpException;
/**
* cURL class
*/
class Curl
{
// ################################################ class vars // ################################################
/**
* @var string
* Holds response data right after sending a request.
*/
public $response = null;
/**
* @var integer HTTP-Status Code
* This value will hold HTTP-Status Code. False if request was not successful.
*/
public $responseCode = null;
/**
* @var array HTTP-Status Code
* Custom options holder
*/
private $_options = array();
/**
* @var object
* Holds cURL-Handler
*/
private $_curl = null;
/**
* @var array default curl options
* Default curl options
*/
private $_defaultOptions = array(
CURLOPT_USERAGENT => 'Yii2-Curl-Agent',
CURLOPT_TIMEOUT => 30,
CURLOPT_CONNECTTIMEOUT => 30,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HEADER => false,
);
// ############################################### class methods // ##############################################
/**
* Start performing GET-HTTP-Request
*
* @param string $url
* @param boolean $raw if response body contains JSON and should be decoded
*
* @return mixed response
*/
public function get($url, $raw = true)
{
return $this->_httpRequest('GET', $url, $raw);
}
/**
* Start performing HEAD-HTTP-Request
*
* @param string $url
*
* @return mixed response
*/
public function head($url)
{
return $this->_httpRequest('HEAD', $url);
}
/**
* Start performing POST-HTTP-Request
*
* @param string $url
* @param boolean $raw if response body contains JSON and should be decoded
*
* @return mixed response
*/
public function post($url, $raw = true)
{
return $this->_httpRequest('POST', $url, $raw);
}
/**
* Start performing PUT-HTTP-Request
*
* @param string $url
* @param boolean $raw if response body contains JSON and should be decoded
*
* @return mixed response
*/
public function put($url, $raw = true)
{
return $this->_httpRequest('PUT', $url, $raw);
}
/**
* Start performing DELETE-HTTP-Request
*
* @param string $url
* @param boolean $raw if response body contains JSON and should be decoded
*
* @return mixed response
*/
public function delete($url, $raw = true)
{
return $this->_httpRequest('DELETE', $url, $raw);
}
/**
* Set curl option
*
* @param string $key
* @param mixed $value
*
* @return $this
*/
public function setOption($key, $value)
{
//set value
if (in_array($key, $this->_defaultOptions) && $key !== CURLOPT_WRITEFUNCTION) {
$this->_defaultOptions[$key] = $value;
} else {
$this->_options[$key] = $value;
}
//return self
return $this;
}
/**
* Unset a single curl option
*
* @param string $key
*
* @return $this
*/
public function unsetOption($key)
{
//reset a single option if its set already
if (isset($this->_options[$key])) {
unset($this->_options[$key]);
}
return $this;
}
/**
* Unset all curl option, excluding default options.
*
* @return $this
*/
public function unsetOptions()
{
//reset all options
if (isset($this->_options)) {
$this->_options = array();
}
return $this;
}
/**
* Total reset of options, responses, etc.
*
* @return $this
*/
public function reset()
{
if ($this->_curl !== null) {
curl_close($this->_curl); //stop curl
}
//reset all options
if (isset($this->_options)) {
$this->_options = array();
}
//reset response & status code
$this->_curl = null;
$this->response = null;
$this->responseCode = null;
return $this;
}
/**
* Return a single option
*
* @param string|integer $key
* @return mixed|boolean
*/
public function getOption($key)
{
//get merged options depends on default and user options
$mergesOptions = $this->getOptions();
//return value or false if key is not set.
return isset($mergesOptions[$key]) ? $mergesOptions[$key] : false;
}
/**
* Return merged curl options and keep keys!
*
* @return array
*/
public function getOptions()
{
return $this->_options + $this->_defaultOptions;
}
/**
* Get curl info according to http://php.net/manual/de/function.curl-getinfo.php
*
* @return mixed
*/
public function getInfo($opt = null)
{
if ($this->_curl !== null && $opt === null) {
return curl_getinfo($this->_curl);
} elseif ($this->_curl !== null && $opt !== null) {
return curl_getinfo($this->_curl, $opt);
} else {
return [];
}
}
/**
* Performs HTTP request
*
* @param string $method
* @param string $url
* @param boolean $raw if response body contains JSON and should be decoded -> helper.
*
* @throws Exception if request failed
*
* @return mixed
*/
private function _httpRequest($method, $url, $raw = false)
{
//set request type and writer function
$this->setOption(CURLOPT_CUSTOMREQUEST, strtoupper($method));
//check if method is head and set no body
if ($method === 'HEAD') {
$this->setOption(CURLOPT_NOBODY, true);
$this->unsetOption(CURLOPT_WRITEFUNCTION);
}
//setup error reporting and profiling
Yii::trace('Start sending cURL-Request: '.$url.'\n', __METHOD__);
Yii::beginProfile($method.' '.$url.'#'.md5(serialize($this->getOption(CURLOPT_POSTFIELDS))), __METHOD__);
/**
* proceed curl
*/
$this->_curl = curl_init($url);
curl_setopt_array($this->_curl, $this->getOptions());
$body = curl_exec($this->_curl);
//check if curl was successful
if ($body === false) {
switch (curl_errno($this->_curl)) {
case 7:
$this->responseCode = 'timeout';
return false;
break;
default:
throw new Exception('curl request failed: ' . curl_error($this->_curl) , curl_errno($this->_curl));
break;
}
}
//retrieve response code
$this->responseCode = curl_getinfo($this->_curl, CURLINFO_HTTP_CODE);
$this->response = $body;
//end yii debug profile
Yii::endProfile($method.' '.$url .'#'.md5(serialize($this->getOption(CURLOPT_POSTFIELDS))), __METHOD__);
//check responseCode and return data/status
if ($this->getOption(CURLOPT_CUSTOMREQUEST) === 'HEAD') {
return true;
} else {
$this->response = $raw ? $this->response : Json::decode($this->response);
return $this->response;
}
}
}
Я очень ценю вашу помощь, я не знаю, что еще попробовать. Спасибо заранее.
Какая ошибка вы получаете от JIRA (код ответа HTTP и его часть?). Если диагностический ответ не помогает, для дальнейшего отладки этого я предлагаю этот подход: Захватите тело HTTP POST, используемого для создания проблемы, удалите все несуществующие детали и отправьте вручную через завиток, затем добавьте обратно части оригинала тело, пока что-то не сломается. Если минимальная проблема JSON не работает, отправьте ее здесь, и я посмотрю. – antonycc
Проблема в том, и я забыл упомянуть об этом в своем оригинальном посте - я не получаю никаких ошибок. Ничего. С моей стороны он создает новую версию в моей системе, но в JIRA ничего не происходит, нет новой проблемы. – Jenny