Hi all,
Have found a workaround that I would like to share with you.
It is helpful in case a report needs to be send back to the enumerator for edits while the enumerator has no Kobo user account.
Note that with a user account and as logged in user, the regular way to edit reports through the enketo interface by url through the kobo api is as described in “Update current submission” in: https://eu.kobotoolbox.org/api/v2/assets/{uid}/data/
But since that currently only seems to work if you happen to be logged in to kobo and since not every enumerator is logged into kobo, the workaround here is helpful.
In short:
Step 1. Use the api to get the content of the report
Step 2. Build a url to a new report and populate the report fields with the data from the old report
Step 3. Send the url to the enumerator for any edits to the report
Step 4. The enumerator submits that newly edited report
Step 5. Use the api to copy the edits of the enumerator to the old report
In detail:
Step 1. Use the api to get the content of the report:
A get request to your instance of the report, for example:
https://eu.kobotoolbox.org/api/v2/assets/{form uid}/data/{report _id}/?format=json
Step 2. Build a url to a new report and populate the report fields with the data from the old report:
Kobo forms can be pre-populated with data by passing the data to the url in this format:
https://ee.kobotoolbox.org/x/{enketo form id }?d [ / {kobo form id} / field_name_1 ]=value_1 & d [ / {kobo form id} / field_name_2 ]=value_2
For example, in practice:
https://ee.kobotoolbox.org/x/6K8reKvt?d[%2FaYY7X8SYjTRw7QNN29tAQ6%2FEntry1]=25&d[%2FaYY7X8SYjTRw7QNN29tAQ6%2FEntry2]=3521&d[%2FaYY7X8SYjTRw7QNN29tAQ6%2Fref]=This_form_overwrites_form:38302492
Here is a snippet in php of how to build the url automatically:
// get the report from kobo:
$old_report = get_report_from_kobo ($report_id);
// exclude system markers like _ or / or "start" or "end" as these should not be changed:
$exclude_these_fields = array();
foreach ($old_report as $field => $key){
if( substr($field, 0, 1) === "_" || strpos($field, "/") !== false || $field === "start" || $field === "end" )
$exclude_these_fields[$field] = $key;
}
$old_report_cleaned = array_diff_key($old_report, $exclude_these_fields);
// construct the url:
$url = "https://ee-eu.kobotoolbox.org/x/$form_id?";
$slash = "%2F";
foreach($old_report_cleaned as $element => $value) {
$url.= "d[" . $slash . $form_xml_uid . $slash . $element . "]=" . $value . "&";
}
// conveniently add a variable that carries the old report ID for automated processing later on; this variable is stored in a kobo field of type hidden
$url.= "d[" . $slash . $form_xml_uid . $slash . "sys_stamp]=" . $report_id;
Step 3. Send the url to the enumerator for any edits to the report:
The url can be easily sent for example by email
Step 4. Submit that newly edited report:
The enumerator can make the edits and submit the report
Step 5. Use the api to copy the edits of the enumerator to the old report:
With both the old report and the new report in hand, the values can be compared and changed on the side of the old report by using the v2 api endpoint:
$url = "https://eu.kobotoolbox.org/api/v2/assets/$kb_form_xml_uid/data/bulk/";
$token = "your_confidential_token"; // when logged in to kobo, this token can be found at https://eu.kobotoolbox.org/token/?format=json
// Create an array with the data that needs the update
$data = [
'submission_ids' => [ strval( $report_id ) ],
'data' => [ strval( $key ) => strval( $value ) ]
];
// Initialize cURL session
$ch = curl_init($url);
$payload = '{"payload":' . json_encode($data) . '}';
// Set cURL options
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PATCH');
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Token ' . $token,
'Content-Type: application/json'
]);
// Run cURL request
$response = curl_exec($ch);
// Close cURL session
curl_close($ch);
// Check for errors
if (curl_errno($ch)) {
$this->write_logfile("edit report field: ", 'cURL error: ' . print_r( curl_error($ch), true ) );
} else {
$this->write_logfile("edit report field: ", 'Response: ' . $response );
}
With the edits now done to the old report, the new report can be deleted and the same effect is reached as with edit report, but now without the enumerator having to be logged in to kobo.