avatar
Creating Jira Issues Using the REST API and Shell Script PHP

• First and foremost, we need to create a Jira account and grant Super Admin permissions. Additionally, we should obtain an API token from Jira.

» api_token

» administrator



• Take of advantage of using the following command to retrieve JSON object containing information about all projects in your Jira instance.

curl --request GET \
  --url 'https://fl-jira.atlassian.net/rest/api/2/project' \
  --user '<username>:<api token>' \
  --header 'Accept: application/json'

Note: Once the base response is returned, we will obtain the project key.

• To get the issue type, follow the same steps as above and use the following command:

curl --request GET \
  --url 'https://fl-jira.atlassian.net/rest/api/2/project/FLAGTICK/statuses' \
  --user '<username>:<api token>' \
  --header 'Accept: application/json'

• Use the following script to create a new issue in a Jira instance

curl --request POST \
  --url 'https://fl-jira.atlassian.net/rest/api/2/issue' \
  --user '<username>:<api token>' \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --data '{
  "fields": {
    "description": "Dummy text.",
    "duedate": "2019-03-11",
    "issuetype": {
      "id": "14512"
    },
    "project": {
      "id": "10002"
    },
    "summary": "New Issue"
  }
}`

• You can use the PHP cURL library to make the POST request to the URL with the given parameters. For example:

function application_form( $fields, $entry, $form_data ) {
    $fields = $entry['fields'];
    $job_in = $entry['fields']['1'];

    $issuetype_id = "11512";
    $data = array(
        'fields' => array(
            'description' => "test",
            'duedate' => '2019-03-11',
            'issuetype' => array(
                'id' => "11512"
            ),
            'project' => array(
                'id' => '12232'
            ),
            'summary' => $job_in
        )
    );

    // Convert the data array to a JSON string
    $json_data = json_encode($data);

    if (function_exists('curl_init')) {
        $url = 'https://fl-jira.atlassian.net/rest/api/2/issue';
        $ch = curl_init();
        
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_USERPWD, '[email protected]:ADFDdfdsfv4V2tccg5O8Sa-VSi-dC49zY-sj4CJJIb8ob7uFYgyzdfdsIZAxYEfdsfdshgVVqSzcfdsRtYpR2bpjEvc22VXatZkmFUEvEXX3DXUAGNvJtsUh_m19JbDTy9DBIejW4M5tLu51omz7p47RG8OILS8EE=8180FD1C');
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json', 'Accept: application/json'));
        curl_setopt($ch, CURLOPT_POSTFIELDS, $json_data);
        
        $response = curl_exec($ch);
        if (curl_errno($ch)) {
            $error_msg = curl_error($ch);
            error_log(json_encode($error_msg));
        } else {
            wpforms()->form->update($form_data);
        }
        curl_close($ch);
    } else {
        error_log('Curl is not enabled');
    }
}
add_action( 'wpforms_process_complete', 'application_form', 10, 3 );

• You need to access Jira dashboard and add custom fields into Jira project. Thus, we have two ways to get custom field.

» First Way: Use the Inspect Element tool in your browser to view the HTML code of a Jira board and identify the ID of the custom field you are interested in:

» Second Way: Use curl command to query Jira API and get the response that shows more details about custom fields

curl --request GET \
  --url 'https://fl-jira.atlassian.net/rest/api/2/field' \
  --user '<username>:<api_token>' \
  --header 'Accept: application/json'

• By using the application_form($fields, $entry, $form_data) function, we can retrieve the file object that was uploaded through the File Upload feature in WPForms plugin 

function application_form( $fields, $entry, $form_data ) {
     ...
     // Set the file path
     $file_path = $fields[ '11' ][ 'value' ];
     // Get the file contents and MIME type
     $file_contents = file_get_contents($file_path);
     $file_mime_type = mime_content_type($file_path);
     $file_name = basename($file_path);
     ...
}  

Note: The Widget ID of WPForms is 11, and this widget allows users to upload files using the drag and drop method.

• Using curl command to attach files to Jira issue key. For example: 

ls -a
curl --location --request POST 'https://fl-jira.atlassian.net/rest/api/3/issue/121643/attachments' \
 -u '<username>:<api token>' \
 -H 'X-Atlassian-Token: no-check'  \
 --form 'file=@"editor.png"'

This is full code for implement WPforms and Jira cloud for integrating both in WordPress website.

function upload_file_to_jira($issue_key, $file_url, $file_name) {
    $file_path = WP_CONTENT_DIR . '/themes/<Your WordPress theme>/wpform/'.$file_name;
    
    if (!is_dir(dirname($file_path))) {
        mkdir(dirname($file_path), 0755, true);
    }
	// Download and save the file contents from the URL
    $file_contents = file_get_contents($file_url);
    $isUploaded = file_put_contents($file_path, $file_contents);
    
    // Download the file and save it to the assets directory
    if ($isUploaded) {
        $attach_file_temp = '/wpform/'.$file_name;
        if (file_exists(__DIR__ . $attach_file_temp)) {
            error_log("$attach_file_temp exists");
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, 'https://fl-jira.atlassian.net/rest/api/3/issue/' . $issue_key . '/attachments');
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_USERPWD, '<username>:<api_token>');
            curl_setopt($ch, CURLOPT_HTTPHEADER, array('X-Atlassian-Token: no-check'));
            curl_setopt($ch, CURLOPT_POSTFIELDS, array('file' => new CURLfile(__DIR__ . $attach_file_temp)));
            $result = curl_exec($ch);
            curl_close($ch);
            unlink(__DIR__ . '/' . $attach_file_temp);
        } else {
            error_log("$attach_file_temp does not exist");
        }
    } else {
        error_log('File save failed');
    }
}

function application_form( $fields, $entry, $form_data ) {

    $porfolio_in = $entry['fields']['9'];
    $fullname_in = $entry['fields']['16']; 
    $email_in = $entry['fields']['41'];
    $phone_number_in = $entry['fields']['18'];
    $location_in = $entry['fields']['19'];
    $cover_letter_in = $entry['fields']['25'];
    $linkedln_profile_in = $entry['fields']['26'];
    $hear_job_in = $entry['fields']['27'];
    $by_whom = $entry['fields']['28'];
    $is_chk = $entry['fields']['32'];

    $issuetype_id = "11512";

    $data = array(
        'fields' => array(
            'description' => "",
            'duedate' => date('Y-m-d'),
            'issuetype' => array(
                'id' => "11512"
            ),
            'customfield_12622' => $porfolio_in,
            'customfield_12623' => $fullname_in,
            'customfield_12624' => $email_in,
            'customfield_12625' => $phone_number_in,
            'customfield_12626' => $location_in,
            'customfield_12627' => $cover_letter_in,
            'customfield_12628' => $linkedln_profile_in,
            'customfield_12629' => $hear_job_in,
            'customfield_12630' => $by_whom,
            'project' => array(
                'id' => '12232'
            ),
            'summary' => $fullname_in
        )
    );

    // Convert the data array to a JSON string
    $json_data = json_encode($data);

    if (function_exists('curl_init')) {
        
        $url = 'https://fl-jira.atlassian.net/rest/api/2/issue';
        // Set up cURL
        $ch = curl_init();
        
        // Set the URL and other cURL options
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_USERPWD, '<username>:<api_token>');
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json', 'Accept: application/json'));
        curl_setopt($ch, CURLOPT_POSTFIELDS, $json_data);
        
        $response = curl_exec($ch);
      
        if (curl_errno($ch)) {
            $error_msg = curl_error($ch);
            error_log(json_encode($error_msg));
        } else {
            $pattern = '/(\d+)"/';
            if (preg_match($pattern, $response, $matches)) {
                $issue_id = $matches[1];
                $file_path = $fields[ '11' ][ 'value' ];
                $file_name = basename($file_path);
                upload_file_to_jira($issue_id, $file_path, $file_name);
            }
            wpforms()->form->update($form_data);
        }
        curl_close($ch);
    } else {
        error_log('Curl is not enabled');
    }
}
add_action( 'wpforms_process_complete', 'application_form', 10, 3 );

Here is possible code structure where functions.php and wpform folder are at the same level:

- root
  - wp-admin
  - wp-content
    - themes
      - <Your WordPress theme>
        - functions.php
        - wpform
          - file.txt
  - wp-includes

• In some cases, data can be stored under HTML tags when a page is created using WP Bakery Page Builder or Elementor plugin. In such cases, we need to extract this data and append the remaining body to be submitted to Jira. Here is an example:

function upload_file_to_jira($issue_key, $file_url, $file_name) {
    $file_path = WP_CONTENT_DIR . '/themes/<Your WordPress theme>/wpform/'.$file_name;
    
    if (!is_dir(dirname($file_path))) {
        mkdir(dirname($file_path), 0755, true);
    }
	// Download and save the file contents from the URL
    $file_contents = file_get_contents($file_url);
    $isUploaded = file_put_contents($file_path, $file_contents);
    
    // Download the file and save it to the assets directory
    if ($isUploaded) {
        $attach_file_temp = '/wpform/'.$file_name;
        if (file_exists(__DIR__ . $attach_file_temp)) {
            error_log("$attach_file_temp exists");
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, 'https://fl-jira.atlassian.net/rest/api/3/issue/' . $issue_key . '/attachments');
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_USERPWD, '<username>:<api_token>');
            curl_setopt($ch, CURLOPT_HTTPHEADER, array('X-Atlassian-Token: no-check'));
            curl_setopt($ch, CURLOPT_POSTFIELDS, array('file' => new CURLfile(__DIR__ . $attach_file_temp)));
            $result = curl_exec($ch);
            curl_close($ch);
            unlink(__DIR__ . '/' . $attach_file_temp);
        } else {
            error_log("$attach_file_temp does not exist");
        }
    } else {
        error_log('File save failed');
    }
}

function get_job_category() {
    $current_slug = get_post_field('post_name', get_post());
    $page = get_page_by_path($current_slug);
    $post_id = $page->ID;
    $content = get_post_field('post_content', $post_id, 'page');
    if (preg_match('/vc_custom_heading.*?text="(.*?)"/', $content, $matches)) {
        $vc_custom_heading = $matches[1];
        return $vc_custom_heading; 
    }
    return '';
}

function get_level_category() {
    $current_slug = get_post_field('post_name', get_post());
    $page = get_page_by_path($current_slug);
    $post_id = $page->ID;
    $content = get_post_field('post_content', $post_id, 'page');

    if (preg_match('/vc_custom_heading text="LEVEL".*?vc_custom_heading text="(.*?)"/', $content, $matches)) {
        $location = $matches[1];
        return $location;
    }   
    return ''; 
}

function get_employment_type_category() {
    $current_slug = get_post_field('post_name', get_post());
    $page = get_page_by_path($current_slug);
    $post_id = $page->ID;
    $content = get_post_field('post_content', $post_id, 'page');

    if (preg_match('/vc_custom_heading text="EMPLOYMENT TYPE".*?vc_custom_heading text="(.*?)"/', $content, $matches)) {
        $location = $matches[1];
        return $location;
    }   
    return ''; 
}

function application_form( $fields, $entry, $form_data ) {

    $porfolio_in = $entry['fields']['9'];
    $fullname_in = $entry['fields']['16']; 
    $email_in = $entry['fields']['41'];
    $phone_number_in = $entry['fields']['18'];
    $location_in = $entry['fields']['19'];
    $cover_letter_in = $entry['fields']['25'];
    $linkedln_profile_in = $entry['fields']['26'];
    $hear_job_in = $entry['fields']['27'];
    $by_whom = $entry['fields']['28'];
    $is_chk = $entry['fields']['32'];

    $issuetype_id = "11512";
    $sumary = get_level_category().' '.get_job_category().' - '.get_employment_type_category();

    $data = array(
        'fields' => array(
            'description' => "",
            'duedate' => date('Y-m-d'),
            'issuetype' => array(
                'id' => "11512"
            ),
            'customfield_12622' => $porfolio_in,
            'customfield_12623' => $fullname_in,
            'customfield_12624' => $email_in,
            'customfield_12625' => $phone_number_in,
            'customfield_12626' => $location_in,
            'customfield_12627' => $cover_letter_in,
            'customfield_12628' => $linkedln_profile_in,
            'customfield_12629' => $hear_job_in,
            'customfield_12630' => $by_whom,
            'project' => array(
                'id' => '12232'
            ),
            'summary' => $sumary
        )
    );

    // Convert the data array to a JSON string
    $json_data = json_encode($data);

    if (function_exists('curl_init')) {
        
        $url = 'https://fl-jira.atlassian.net/rest/api/2/issue';

        // Set up cURL
        $ch = curl_init();
        
        // Set the URL and other cURL options
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_USERPWD, '<username>:<api token>');
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json', 'Accept: application/json'));
        curl_setopt($ch, CURLOPT_POSTFIELDS, $json_data);
        
        $response = curl_exec($ch);
        
        if (curl_errno($ch)) {
            $error_msg = curl_error($ch);
            error_log(json_encode($error_msg));
        } else {
            $pattern = '/(\d+)"/';
            if (preg_match($pattern, $response, $matches)) {
                $issue_id = $matches[1];
                $file_path = $fields[ '11' ][ 'value' ];
                $file_name = basename($file_path);
                upload_file_to_jira($issue_id, $file_path, $file_name);
            }
            wpforms()->form->update($form_data);
        }
        curl_close($ch);
    } else {
        error_log('Curl is not enabled');
    }
}

add_action( 'wpforms_process_complete', 'application_form', 10, 3 );

In some cases, you're experiencing with file_get_contents() not working with an HTTPS URL, you can try using the curl extension instead.

function upload_file_to_jira($issue_key, $file_url, $file_name) {
    $file_path = WP_CONTENT_DIR . '/themes/<Your WordPress theme>/wpform/'.$file_name;
    
    if (!is_dir(dirname($file_path))) {
        mkdir(dirname($file_path), 0755, true);
    }
    
    // Download and save the file contents from the URL
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $file_url);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    $file_contents = curl_exec($curl);
    $isUploaded = file_put_contents($file_path, $file_contents);
    
    // Download the file and save it to the assets directory
    if ($isUploaded) {
        $attach_file_temp = '/wpform/'.$file_name;

        if (file_exists(__DIR__ . $attach_file_temp)) {
            error_log("$attach_file_temp exists");
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, 'https://fl-jira.atlassian.net/rest/api/3/issue/' . $issue_key . '/attachments');
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_USERPWD, '<username>:<api token>');
            curl_setopt($ch, CURLOPT_HTTPHEADER, array('X-Atlassian-Token: no-check'));
            curl_setopt($ch, CURLOPT_POSTFIELDS, array('file' => new CURLfile(__DIR__ . $attach_file_temp)));
            $result = curl_exec($ch);
            curl_close($ch);
            unlink(__DIR__ . '/' . $attach_file_temp);
        } else {
            error_log("$attach_file_temp does not exist");
        }
    } else {
        error_log('File save failed');
    }
}

Happy referencing!

You need to login to do this manipulation!