public function test_add_status_resolved_call_task_multiple_times() { $data = array('number' => '00000000000000', 'assignee_uid' => 1, 'activity' => array()); $call_task = new Call_task_entity($data); $this->assertInstanceOf('Call_task_entity', $call_task->add_status(Call_task_status::create(Call_task_status::NO_REPLY, 'NO_REPLY'))); $this->assertInstanceOf('Call_task_entity', $call_task->add_status(Call_task_status::create(Call_task_status::NO_REPLY, 'NO_REPLY'))); $this->assertInstanceOf('Call_task_entity', $call_task->add_status(Call_task_status::create(Call_task_status::NO_REPLY, 'NO_REPLY'))); $this->assertInstanceOf('Call_task_entity', $call_task->add_status(Call_task_status::create(Call_task_status::CANT_COMPLETE, 'CANT_COMPLETE'))); $this->assertInstanceOf('Call_task_entity', $call_task->add_status(Call_task_status::create(Call_task_status::CANT_COMPLETE, 'CANT_COMPLETE'))); $this->assertInstanceOf('Call_task_entity', $call_task->add_status(Call_task_status::create(Call_task_status::CANT_COMPLETE, 'CANT_COMPLETE'))); $this->assertInstanceOf('Call_task_entity', $call_task->add_status(Call_task_status::create(Call_task_status::NO_REPLY, 'NO_REPLY'))); $this->assertInstanceOf('Call_task_entity', $call_task->add_status(Call_task_status::create(Call_task_status::SUCCESSFUL, 'SUCCESSFUL'))); $this->assertEquals(Call_task_status::SUCCESSFUL, $call_task->activity[7]->code); $this->assertEquals('SUCCESSFUL', $call_task->activity[7]->message); }
/** * Enekto API * Enketo submission handler. * * JSON output: * status : { * code : , * message: * } */ public function api_survey_enketo_form_submit($sid) { $survey = $this->survey_model->get($sid); if (!$survey) { return $this->api_output(404, 'Invalid survey.', array('respondents' => NULL)); } else { if (!$survey->has_xml()) { return $this->api_output(500, 'Xml file not present.', array('xml_form' => NULL)); } else { if (!has_permission('enketo collect data any') && !has_permission('enketo collect data assigned')) { return $this->api_output(403, 'Not allowed.', array('respondents' => NULL)); } else { if (has_permission('enketo collect data any')) { if (!$survey->status_allows('enketo collect data')) { return $this->api_output(403, 'Not allowed.', array('respondents' => NULL)); } } else { if (!has_permission('enketo collect data any') && has_permission('enketo collect data assigned')) { // Must be assigned and correct status if (!$survey->is_assigned_agent(current_user()->uid) || !$survey->status_allows('enketo collect data')) { return $this->api_output(403, 'Not allowed.', array('respondents' => NULL)); } } } } } } $respondent = $this->input->post('respondent'); $ctid = (int) $respondent['ctid']; $call_task = $this->call_task_model->get($ctid); if (!$call_task || $call_task->survey_sid == NULL) { return $this->api_output(500, 'Invalid call task.'); } else { if (!$call_task->is_assigned()) { return $this->api_output(500, 'User not assigned to call task.'); } } // After knowing that the call task is valid, knowing to who it belongs // is the first thing. All the other validations will be done when // the data is submitted under the right circumstances. // If the same computer is shared by different users it may happen // that an user uploads data another user left in the localStorage. // We do not save that data, but we send a response to keep it in // the localstorage. // The call task can't be resolved. // There has to be someone assigned to it. if (!$call_task->is_resolved() && $call_task->is_assigned()) { // If another user is assigned send response. if (current_user()->uid != $call_task->assignee_uid) { return $this->api_output(201, 'Submitting data for another user.'); } else { if ($call_task->is_assigned(current_user()->uid) && $call_task->survey_sid != $sid) { return $this->api_output(201, 'Submitting data for another survey.'); } } } // Reaching this point we know: // - Call task is assigned to the current_user. // - The survey to which the call task is assigned is the one for // which data is being submitted. // Now that we know that the call task does not belong to another user // let's do some more validations. if (!has_permission('enketo collect data any') && has_permission('enketo collect data assigned')) { // Is the user assigned? if (!$survey->is_assigned_agent(current_user()->uid)) { return $this->api_output(403, 'Not allowed.'); } } // Was the survey completed? // If there's a form_data it's finished if (isset($respondent['form_data'])) { // Check if the data is valid. // Restore error handler to PHP to 'catch' libxml 'errors' restore_error_handler(); libxml_use_internal_errors(true); //clear any previous errors libxml_clear_errors(); // Construct object. $doc = simplexml_load_string($respondent['form_data']); $errors = libxml_get_errors(); // Empty errors libxml_clear_errors(); // Restore CI error handler set_error_handler('_exception_handler'); if (!empty($errors)) { return $this->api_output(500, 'Invalid data.'); } // Load model $this->load->model('survey_result_model'); $survey_result_data = array('call_task_ctid' => $call_task->ctid, 'survey_sid' => $survey->sid); $survey_result = Survey_result_entity::build($survey_result_data); // Save result to get an ID if (!$this->survey_result_model->save($survey_result)) { // The data is valid but save failed. return $this->api_output(201, 'Saving survey result failed.'); } // Save data to file. $survey_result->save_xml($doc->asXML()); // Save again. // If the save files, delete file. if (!$this->survey_result_model->save($survey_result)) { // Attempt to delete the uploaded file. if (file_exists($survey_result->get_xml_full_path())) { unlink($survey_result->get_xml_full_path()); } // The data is valid but save failed. return $this->api_output(201, 'Saving survey result failed.'); } // Set successful status. try { $call_task->add_status(Call_task_status::create(Call_task_status::SUCCESSFUL, '')); } catch (Exception $e) { return $this->api_output(500, 'Trying to submit data for a resolved call task.'); } } elseif (isset($respondent['new_status']['code']) && isset($respondent['new_status']['msg'])) { $new_status_code = (int) $respondent['new_status']['code']; if ($new_status_code == Call_task_status::SUCCESSFUL) { return $this->api_output(500, 'Successful status can not be set manually.'); } try { $new_status = Call_task_status::create($new_status_code, xss_clean(trim($respondent['new_status']['msg']))); $call_task->add_status($new_status); } catch (Exception $e) { return $this->api_output(500, 'Invalid call task status.'); } } else { // No form_data or new_status found. Error. return $this->api_output(500, 'Missing data form_data and new_status.'); } $this->call_task_model->save($call_task); return $this->api_output(); }