/**
  * Returns all the survey results of a given survey.
  *  
  * @param int $sid
  *  Since all the survey results are bound to a survey its id is needed.
  * 
  * @return array of Survey_result_entity
  */
 public function get_all($sid)
 {
     $result = $this->mongo_db->where('survey_sid', (int) $sid)->get(self::COLLECTION);
     $survey_results = array();
     foreach ($result as $value) {
         $survey_results[] = Survey_result_entity::build($value);
     }
     return $survey_results;
 }
示例#2
0
 /**
  * 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();
 }