0

I'm trying to post form data to an API using PHP. The API requires that the screening_questions have duplicate keys, like so:

enter image description here

I've gotten as far as having all fields correctly in the array to send except for the screening questions, which are multiple arrays inside the main array. I need to flatten or merge them so that the screening_questions aren't in nested arrays, but while attempting to do so it returns just the last screening_questions array since they all have the same key.

So this array:

Array
(
    [candidate[resume]] => CURLFile Object
        (
            [name] => /nas/content/live/powerhrg2/wp-content/uploads/gravity_forms/5-51403278f6166fe42c507d417f729fc5/2023/02/Power-HRG-Tech-Spec256.pdf
            [mime] => application/pdf
            [postname] => Power-HRG-Tech-Spec256.pdf
        )
    [candidate[first_name]] => John
    [candidate[last_name]] => Johnson
    [candidate[email]] => john.johnson@email.net
    [candidate[phone]] => 555-555-5555
    [job_posting_public_id] => 28038a67e70c7e235fa725bbf8b6e167d9e3efee1e43a304d73be8408c6f24a2
    [candidate[source_id]] => 7795
    [0] => Array
        (
            [screening_questions[][id]] => 1
            [screening_questions[][answer]] => false
        )
    [1] => Array
        (
            [screening_questions[][id]] => 6
            [screening_questions[][answer]] => true
        )
    [2] => Array
        (
            [screening_questions[][id]] => 11
            [screening_questions[][answer]] => true
        )
    [3] => Array
        (
            [screening_questions[][id]] => 16
            [screening_questions[][answer]] => true
        )
)

Should be this:

Array
(
    [candidate[resume]] => CURLFile Object
        (
            [name] => /nas/content/live/powerhrg2/wp-content/uploads/gravity_forms/5-51403278f6166fe42c507d417f729fc5/2023/02/Power-HRG-Tech-Spec256.pdf
            [mime] => application/pdf
            [postname] => Power-HRG-Tech-Spec256.pdf
        )
    [candidate[first_name]] => John
    [candidate[last_name]] => Johnson
    [candidate[email]] => john.johnson@email.net
    [candidate[phone]] => 555-555-5555
    [job_posting_public_id] => 28038a67e70c7e235fa725bbf8b6e167d9e3efee1e43a304d73be8408c6f24a2
    [candidate[source_id]] => 7795
    [screening_questions[][id]] => 1
    [screening_questions[][answer]] => false
    [screening_questions[][id]] => 6
    [screening_questions[][answer]] => true
    [screening_questions[][id]] => 11
    [screening_questions[][answer]] => true
    [screening_questions[][id]] => 16
    [screening_questions[][answer]] => true
)

I can't think of a way to merge or flatten those arrays?

I've only ever dealt with sending array data via POST - is there another way I can format this so that I can have these duplicated screening_questions with unique values?

Any help is greatly appreciated.

Here is my code in it's entirety:

add_action( 'gform_after_submission_5', 'post_to_third_party', 10, 2 );
function post_to_third_party( $entry, $form ) {
    // get regular form field data
    $first_name = rgar( $entry, '1' );
    $last_name = rgar( $entry, '3' );
    $phone = rgar( $entry, '11' );
    $phone = preg_replace("/[^0-9]/", "", $phone);
    $phone = preg_replace('/^1?(\d{3})(\d{3})(\d{4})$/', '$1-$2-$3', $phone);
    $email = rgar( $entry, '6' );
    $resume = GFFormsModel::get_physical_file_path( rgar( $entry, '7' ) );
    $resume = new CURLFile($resume, mime_content_type($resume), basename($resume));
    $job = get_job(); // get current job ID & source ID
    $job_id = $job['id'];
    $source_id = $job['source_id'];
    // get screening questions id & answer data
    foreach ( $form['fields'] as $field ) {
        if ($field['type'] === 'radio') {
            $field_values[] = preg_replace('/[^0-9.]/', '', $field->get_value_export( $entry, $field->id )); // i.e. converts 'yes-1' to '1' 
            $field_names[]  = $field->get_value_export( $entry, $field->id, true ); // yes
        }
    }
    // remove empty data
    $field_values = array_slice(array_filter($field_values),0);
    $field_names = array_slice(array_filter($field_names),0);
    
    // combine screening id & answer
    $screening_questions = array_combine($field_values, $field_names);
    foreach ($screening_questions as $screening_question=>$sq) {
        // value must be true/false, not yes/no
        if ($sq == 'yes') {
            $sq = 'true';
        } else {
            $sq = 'false';
        }
        $question[] = array('screening_questions[][id]' => $screening_question, 'screening_questions[][answer]' => $sq);
    }
    // create an array of form data to send via the API
    $body = array(
        'candidate[resume]' => $resume,
        'candidate[first_name]' => $first_name,
        'candidate[last_name]' => $last_name,
        'candidate[email]' => $email,
        'candidate[phone]' => $phone,
        'job_posting_public_id' => $job_id,
        'candidate[source_id]' => $source_id,
    );
    foreach ($question as $q) {
        array_push($body,$q);
    }
    $post_url = 'https://pr29718.nitro-web.beta.hq.powerapp.cloud/recruiting/api/v2/candidates'; // TEST URL
    $pass = 'AMC0HNUK30RTFATWWKBJTW'; // TEST TOKEN
    $headers = array(
        'Host: pr29718.nitro-web.beta.hq.powerapp.cloud',
        'Authorization: '.$pass,
    );
    // Uncomment the below line to debug, if necessary
    GFCommon::log_debug( 'gform_after_submission: body => ' . print_r( $body, true ) );
    // Uncomment the below line to debug, if necessary
    GFCommon::log_debug( 'gform_after_submission: headers => ' . print_r( $headers, true ) );
    // Nitro API request via cURL
    $curl = curl_init();
    curl_setopt_array($curl, array(
        CURLOPT_URL => 'https://pr29718.nitro-web.beta.hq.powerapp.cloud/recruiting/api/v2/candidates',
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_ENCODING => '',
        CURLOPT_MAXREDIRS => 10,
        CURLOPT_TIMEOUT => 0,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
        CURLOPT_CUSTOMREQUEST => 'POST',
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => $body,
        CURLOPT_HEADER => true,
        CURLOPT_HTTPHEADER => $headers,
    ));
    $response = curl_exec($curl);
    curl_close($curl);
    // Uncomment below line to debug, if necessary
    GFCommon::log_debug( 'gform_after_submission: response => ' . print_r( $response, true ) );
}
mickmackusa
  • 43,625
  • 12
  • 83
  • 136
Trisha
  • 539
  • 3
  • 10
  • 30
  • Rather than sanitizing the phone number then formatting it, do it in one step. `$phone = preg_replace('/^\D*1?\D*(\d{3})\D*(\d{3})\D*(\d{4})\D*$/', '$1-$2-$3', $phone);` `\D` means a non-digit character. `*` means "zero or more". `array_slice()` from the first element onward is weird tool for what `array_values()` is built to do. https://3v4l.org/42a97 But to be honest, `array_combine()` doesn't need indexed arrays anyhow -- it doesn't care about the keys. – mickmackusa Feb 09 '23 at 00:26
  • Just add your new associative elements directly to `$body` in your `foreach (`$screening_questions...` loop. You don't need to overwrite `$sq` with that condition block -- when access the boolean `$sq`, just use the comparison's return value: `'screening_questions[][answer]' => $sq == 'yes'` – mickmackusa Feb 09 '23 at 00:41

1 Answers1

0

I think the parameter sending is wrongly defined. just put the subarray in the screening_questions[] array, what is the API response?

//next time pls define the variable before use.
$question = array();
foreach ($screening_questions as $screening_question=>$sq) {
  // value must be true/false, not yes/no
  $question[] = array(
    'id'     => $screening_question, 
    'answer' => $sq === 'true' ? 'true' : 'false'
  );
}

$body = array(
   'candidate[resume]' => $resume,
   'candidate[first_name]' => $first_name,
   'candidate[last_name]' => $last_name,
   'candidate[email]' => $email,
   'candidate[phone]' => $phone,
   'job_posting_public_id' => $job_id,
   'candidate[source_id]' => $source_id,
   'screening_questions' => $question,
);

neurodede
  • 100
  • 6
  • `$sq === 'true' ? 'true' : 'false'` should be `$sq === 'yes'`. And `$question[]` should be pushing directly into `$body` with `$body['screening_questions'][] = ...` (with `$body` declared before the loop, of course.) – mickmackusa Feb 09 '23 at 00:42