diff --git a/.gitmodules b/.gitmodules
index acfb63e..66f828b 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -7,3 +7,6 @@
[submodule "assets/libs/enketo-core"]
path = assets/libs/enketo-core
url = git@github.com:MartijnR/enketo-core.git
+[submodule "src/vendor/jquery-toastmessage"]
+ path = src/vendor/jquery-toastmessage
+ url = git@github.com:akquinet/jquery-toastmessage-plugin.git
diff --git a/Gruntfile.js b/Gruntfile.js
index e813743..b58e08e 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -94,6 +94,7 @@ module.exports = function(grunt) {
'assets/scripts/website.min.js': [
'src/vendor/chosen/chosen.jquery.min.js',
+ 'src/vendor/jquery-toastmessage/src/main/javascript/jquery.toastmessage.js',
'src/scripts/*.js'
],
}
@@ -106,6 +107,7 @@ module.exports = function(grunt) {
files : {
'assets/styles/main.css' : [
'src/vendor/chosen/chosen.css',
+ 'src/vendor/jquery-toastmessage/src/main/resources/css/jquery.toastmessage.css',
'src/temp/path_override.css',
'src/temp/main.css'
]
@@ -115,6 +117,7 @@ module.exports = function(grunt) {
files : {
'assets/styles/main.css' : [
'src/vendor/chosen/chosen.min.css',
+ 'src/vendor/jquery-toastmessage/src/main/resources/css/jquery.toastmessage.css',
'src/temp/path_override.css',
'src/temp/main.css'
]
diff --git a/application/config/config.php b/application/config/config.php
index a76f74e..5d216c2 100644
--- a/application/config/config.php
+++ b/application/config/config.php
@@ -14,8 +14,8 @@
| path to your installation.
|
*/
-//$config['base_url'] = 'http://dev/airwolf2.0/aw-datacollection/';
$config['base_url'] = 'http://192.168.99.10/work/aw-datacollection/';
+//$config['base_url'] = '/work/aw-datacollection/';
/*
|--------------------------------------------------------------------------
@@ -384,5 +384,11 @@
$config['aw_respondents_per_page'] = 50;
+/**
+ * Email settings and admin data
+ */
+$config['aw_admin_name'] = 'Aw-datacollection Admin';
+$config['aw_admin_email'] = 'aw-datacollection@airwolf.edispilf.org';
+
/* End of file config.php */
/* Location: ./application/config/config.php */
\ No newline at end of file
diff --git a/application/config/routes.php b/application/config/routes.php
index 1d7d23c..93f1aab 100644
--- a/application/config/routes.php
+++ b/application/config/routes.php
@@ -47,7 +47,7 @@
$route['survey/add'] = 'survey/survey_add';
$route['survey/(:num)'] = 'survey/survey_by_id/$1';
$route['survey/(:num)/edit'] = 'survey/survey_edit_by_id/$1';
-$route['survey/delete'] = 'survey/survey_delete_by_id';
+$route['survey/(:num)/delete'] = 'survey/survey_delete_by_id/$1';
$route['survey/(:num)/files/(xls|xml)'] = 'survey/survey_file_download/$1/$2';
$route['survey/(:num)/(testrun|data_collection)'] = 'survey/survey_enketo/$1/$2';
// respondents
@@ -74,7 +74,7 @@
// Users
$route['login'] = 'user/user_login';
$route['logout'] = 'user/user_logout';
-$route['user'] = 'user/user_profile';
+//$route['user'] = 'user/user_profile'; As of right now profiles are disabled.
$route['user/(:num)/edit'] = 'user/user_edit_by_id/$1';
$route['user/recover'] = 'user/user_recover_password';
$route['user/reset_password/(:any)'] = 'user/user_reset_password/$1';
diff --git a/application/controllers/index.php b/application/controllers/index.php
index 7af6a92..9e225bf 100644
--- a/application/controllers/index.php
+++ b/application/controllers/index.php
@@ -5,12 +5,22 @@ class Index extends CI_Controller {
public function __construct() {
parent::__construct();
}
+
+ public function test() {
+ $this->load->view('base/html_start');
+ $this->load->view('frontend');
+ $this->load->view('base/html_end');
+ }
public function index() {
- $this->load->view('base/html_start');
- $this->load->view('navigation');
+ if (!is_logged()) {
+ redirect('login');
+ }
$this->load->model('survey_model');
+ $this->load->view('base/html_start');
+ $this->load->view('components/navigation', array('active_menu' => 'dashboard'));
+
// Use the same permissions for the list but use different statuses.
$surveys = array();
if (has_permission('view survey list any')) {
@@ -23,21 +33,22 @@ public function index() {
}
// TEMP
+ $data = '';
if ($surveys) {
- $this->output->append_output('Your surveys:
');
+ $data = 'Your surveys:
';
foreach ($surveys as $survey) {
- $this->output->append_output('-' . $survey->title . '
');
+ $data .= '-' . $survey->title . '
';
}
ob_start();
krumo($surveys);
- $this->output->append_output(ob_get_clean());
+ $data .= ob_get_clean();
}
// /TEMP
-
-
+
+ $this->load->view('dashboard', array('data' => $data));
$this->load->view('base/html_end');
}
}
diff --git a/application/controllers/survey.php b/application/controllers/survey.php
index ccf0db9..1cc859f 100644
--- a/application/controllers/survey.php
+++ b/application/controllers/survey.php
@@ -37,7 +37,7 @@ public function index() {
* Route:
* /surveys
*/
- public function surveys_list(){
+ public function surveys_list(){
if (!has_permission('view survey list any') && !has_permission('view survey list assigned')) {
show_403();
}
@@ -55,7 +55,7 @@ public function surveys_list(){
}
$this->load->view('base/html_start');
- $this->load->view('navigation');
+ $this->load->view('components/navigation', array('active_menu' => 'surveys'));
$this->load->view('surveys/survey_list', array('surveys' => $surveys));
$this->load->view('base/html_end');
@@ -84,11 +84,8 @@ public function survey_by_id($sid){
}
}
- $messages = Status_msg::get();
$data = array(
- 'survey' => $survey,
- //'messages' => $messages,
- 'messages' => $this->load->view('messages', array('messages' => $messages), TRUE)
+ 'survey' => $survey
);
// Agents. Each array element contains the user and
@@ -111,7 +108,7 @@ public function survey_by_id($sid){
$data['agents'] = $agents;
$this->load->view('base/html_start');
- $this->load->view('navigation');
+ $this->load->view('components/navigation', array('active_menu' => 'surveys'));
$this->load->view('surveys/survey_page', $data);
$this->load->view('base/html_end');
@@ -182,7 +179,7 @@ protected function _survey_form_handle($action = 'add', $survey = null) {
// If no data submitted show the form.
if ($this->form_validation->run() == FALSE) {
$this->load->view('base/html_start');
- $this->load->view('navigation');
+ $this->load->view('components/navigation', array('active_menu' => 'surveys'));
$this->load->view('surveys/survey_form', array('survey' => $survey));
$this->load->view('base/html_end');
}
@@ -276,24 +273,28 @@ protected function _survey_form_handle($action = 'add', $survey = null) {
/**
* Delete handler for surveys.
- * Route (POST data)
- * /survey/delete
+ * Route
+ * /survey/:sid/delete
*/
- public function survey_delete_by_id(){
+ public function survey_delete_by_id($sid){
+ verify_csrf_get();
+
if (!has_permission('delete any survey')) {
show_403();
}
-
- $this->form_validation->set_rules('survey_sid', 'Survey ID', 'required|callback__cb_survey_exists');
- $sid = $this->input->post('survey_sid');
-
- if ($this->form_validation->run() == TRUE) {
- $this->survey_model->delete($sid);
+
+ $survey = $this->survey_model->get($sid);
+ if (!$survey) {
+ show_404();
+ }
+
+ if ($this->survey_model->delete($sid)) {
+ Status_msg::success('Survey successfully deleted.');
}
else {
- // Survey Id has been tempered with.
- show_error("An error occurred while deleting the survey.");
+ Status_msg::error('An error occurred while deleting the survey.');
}
+
redirect('/surveys');
}
@@ -333,26 +334,29 @@ public function survey_enketo($sid, $type) {
else if (!$survey->has_xml()) {
show_403();
}
-
+
+ // If can collect|testrun any let through, otherwise must be assigned.
switch ($type) {
case 'data_collection':
- if (!has_permission('enketo collect data any') && !has_permission('enketo collect data assigned')) {
- show_403();
-
- }else if (!has_permission('enketo collect data any') && has_permission('enketo collect data assigned')) {
- // Is assigned?
- if (!$survey->is_assigned_agent(current_user()->uid)) {
- show_403();
- }
- }
+ $perm_any = 'enketo collect data any';
+ $perm_assigned = 'enketo collect data assigned';
break;
case 'testrun':
- if (!has_permission('enketo testrun any') && !has_permission('enketo testrun assigned')) {
- show_403();
- }
+ $perm_any = 'enketo testrun any';
+ $perm_assigned = 'enketo testrun assigned';
break;
}
+
+ if (!has_permission($perm_any) && !has_permission($perm_assigned)) {
+ show_403();
+
+ }else if (!has_permission($perm_any) && has_permission($perm_assigned)) {
+ // Is assigned?
+ if (!$survey->is_assigned_agent(current_user()->uid)) {
+ show_403();
+ }
+ }
// Needed urls.
$settings = array(
@@ -366,7 +370,7 @@ public function survey_enketo($sid, $type) {
$this->js_settings->add($settings);
$this->load->view('base/html_start', array('using_enketo' => TRUE, 'enketo_action' => $type));
- $this->load->view('navigation');
+ $this->load->view('components/navigation', array('active_menu' => 'surveys'));
$this->load->view('surveys/survey_enketo', array('survey' => $survey, 'enketo_action' => $type));
$this->load->view('base/html_end');
@@ -415,7 +419,7 @@ public function survey_enketo_single($sid, $ctid) {
$this->js_settings->add($settings);
$this->load->view('base/html_start', array('using_enketo' => TRUE, 'enketo_action' => 'data_collection_single'));
- $this->load->view('navigation');
+ $this->load->view('components/navigation', array('active_menu' => 'surveys'));
$this->load->view('surveys/survey_enketo', array('survey' => $survey, 'call_task' => $call_task, 'enketo_action' => 'data_collection_single'));
$this->load->view('base/html_end');
}
@@ -454,7 +458,7 @@ public function survey_call_activity($sid) {
$unresolved = $this->call_task_model->get_unresolved($sid, current_user()->uid);
$this->load->view('base/html_start');
- $this->load->view('navigation');
+ $this->load->view('components/navigation', array('active_menu' => 'surveys'));
$this->load->view('surveys/survey_call_activity', array(
'survey' => $survey,
'call_tasks_resolved' => $resolved,
@@ -463,6 +467,243 @@ public function survey_call_activity($sid) {
$this->load->view('base/html_end');
}
+ /**
+ * Summary page to list the respondents associated to a given survey.
+ * @param $sid
+ *
+ * Route - /survey/:sid/respondents/:page
+ */
+ public function survey_respondents($sid, $page = 1){
+ $page = $page < 1 ? 1 : $page;
+ $survey = $this->survey_model->get($sid);
+ if (!$survey) {
+ show_404();
+ }
+ else if (!has_permission('manage respondents any survey')) {
+ show_403();
+ }
+
+ // Respondents to show per page.
+ $respondents_pp = $this->config->item('aw_respondents_per_page');
+ $this->load->library('pagination');
+
+ // Prepare pagination.
+ $this->pagination->initialize(array(
+ 'base_url' => $survey->get_url_respondents(),
+ 'use_page_numbers' => TRUE,
+ 'uri_segment' => 4,
+ 'total_rows' => $this->call_task_model->get_total_count($sid),
+ 'per_page' => $respondents_pp,
+ //'cur_tag_open' => '',
+ //'cur_tag_close' => '',
+ ));
+
+ $respondents = $this->call_task_model->get_all_paginated($sid, $page, $respondents_pp);
+
+ $data = array(
+ 'survey' => $survey,
+ 'respondents' => $respondents,
+ );
+
+ $this->load->view('base/html_start');
+ $this->load->view('components/navigation', array('active_menu' => 'surveys'));
+ $this->load->view('surveys/survey_respondents', $data);
+ $this->load->view('base/html_end');
+ }
+
+ /**
+ * Summary page to add respondents to a given survey.
+ * @param $sid
+ *
+ * Route - /survey/:sid/respondents
+ */
+ public function survey_respondents_add($sid){
+ $survey = $this->survey_model->get($sid);
+ if (!$survey) {
+ show_404();
+ }
+ else if (!has_permission('manage respondents any survey')) {
+ show_403();
+ }
+
+ // Config data for the file upload.
+ $file_upload_config = array(
+ 'upload_path' => '/tmp/',
+ 'allowed_types' => 'csv',
+ 'file_name' => 'respondents_' . md5(microtime(true))
+ );
+
+ // Load needed libraries
+ $this->load->library('upload', $file_upload_config);
+
+ $this->form_validation->set_rules('survey_respondents_file', 'Respondents File', 'callback__cb_survey_respondents_add_file_handle');
+ $this->form_validation->set_rules('survey_respondents_text', 'Respondents Text', 'xss_clean');
+
+ // If no data submitted show the form.
+ if ($this->form_validation->run() == FALSE) {
+
+ $this->load->view('base/html_start');
+ $this->load->view('components/navigation', array('active_menu' => 'surveys'));
+ $this->load->view('surveys/survey_respondents_add', array('survey' => $survey));
+ $this->load->view('base/html_end');
+ }
+ else {
+ // Initialize the respondents numbers list.
+ $rows = explode("\n", $this->input->post('survey_respondents_text'));
+ $textarea_lines = sizeof($rows);
+ $respondents_numbers = array();
+
+ // Read file, if any.
+ $file = $this->input->post('survey_respondents_file');
+
+ if (isset($file['full_path'])) {
+ // Load CSVReader library.
+ $this->load->helper('csvreader');
+ $csv = new CSVReader();
+ $csv->separator = ',';
+ // We are merging the rows from csv to potential rows in the text area
+ // this allows to verify everything in one pass.
+ $rows = array_merge($rows, $csv->parse_file($file['full_path']));
+ }
+
+ $db_call_tasks = $this->call_task_model->get_all($sid);
+
+ foreach ($rows as $line => $row) {
+ // Silently skip empty rows.
+ if (empty($row)) {
+ continue;
+ }
+
+ // Prepare data.
+ // If it's a row from the text area.
+ if (!is_array($row)) {
+ $context = 'textarea';
+ $real_line = $line + 1;
+ $row = trim($row);
+ }
+ // This is from the csv file.
+ else {
+ $context = 'CSV file';
+ $real_line = ($line + 1) - $textarea_lines;
+ // Make sure it's not a random CSV.
+ if (isset($row[SURVEY_RESPONDENT_CSV_HEADER])) {
+ $row = trim($row[SURVEY_RESPONDENT_CSV_HEADER]);
+ }
+ // Warn user.
+ else {
+ Status_msg::warning('Some data has been skipped. Make sure your column header is "' . SURVEY_RESPONDENT_CSV_HEADER .'".');
+ }
+ }
+
+ // Common checks.
+ // @todo check also if already present in the DB
+ // hint: check $row against $object->number
+ if (is_numeric($row)) {
+
+ // Check db doubles.
+ $is_double = FALSE;
+ foreach ($db_call_tasks as $call_task) {
+ if ($call_task->number == $row) {
+ $is_double = TRUE;
+ break;
+ }
+ }
+
+ if ($is_double) {
+ // Db Double.
+ continue;
+ }
+ // END Check db doubles.
+
+ if (!isset($respondents_numbers[$row])) {
+ $respondents_numbers[$row] = 0;
+ }
+ $respondents_numbers[$row]++;
+ }
+ else {
+ Status_msg::warning("Line #$real_line of the $context has been skipped as it does not appear to be a number.");
+ }
+ }
+
+ // Store in session or issue error if.
+ if (sizeof($respondents_numbers)) {
+ $_SESSION['respondents_numbers'] = $respondents_numbers;
+ }
+ else {
+ Status_msg::error('No usable numbers have been found in submitted data.');
+ redirect('/survey/' . $survey->sid . '/respondents');
+ }
+
+ // Perform the redirect.
+ redirect('/survey/' . $survey->sid . '/respondents/add/confirm');
+ }
+ }
+
+ /**
+ * Summary page to add respondents to a given survey.
+ * @param $sid
+ *
+ * Route - /survey/:sid/respondents
+ */
+ public function survey_respondents_add_confirm($sid){
+ $survey = $this->survey_model->get($sid);
+ if (!$survey) {
+ show_404();
+ }
+ else if (!has_permission('manage respondents any survey')) {
+ show_403();
+ }
+
+ $data = array(
+ 'survey' => $survey,
+ 'respondents_numbers' => array(),
+ );
+
+ // pass on the data to the view
+ if (isset($_SESSION['respondents_numbers'])) {
+ $data['respondents_numbers'] = array_keys($_SESSION['respondents_numbers']);
+ }
+
+ $this->form_validation->set_rules('survey_respondents_submit', '', 'required');
+
+ // If no data submitted show the form.
+ if ($this->form_validation->run() == FALSE) {
+
+ $this->load->view('base/html_start');
+ $this->load->view('components/navigation', array('active_menu' => 'surveys'));
+ $this->load->view('surveys/survey_respondents_confirm', $data);
+ $this->load->view('base/html_end');
+ }
+ else {
+
+ // create a call_task for each respondent number
+ foreach ($_SESSION['respondents_numbers'] as $number => $qtd) {
+ // Prepare survey data to construct a new survey_entity
+ $call_task_data = array();
+ // @todo find generic solution for the code below (int)
+ $call_task_data['survey_sid'] = (int) $sid;
+ $call_task_data['number'] = (string) $number;
+
+ // Construct survey.
+ $new_call_task = Call_task_entity::build($call_task_data);
+
+ // Save survey.
+ // Survey files can only be handled after the survey is saved.
+ // TODO: Handle error during save.
+ $this->call_task_model->save($new_call_task);
+ }
+
+ // User feedback.
+ $numbers = sizeof($_SESSION['respondents_numbers']);
+ Status_msg::success("Added $numbers entries to the call tasks of this survey.");
+
+ unset($_SESSION['respondents_numbers']);
+
+ // perform the redirect
+ redirect('/survey/' . $survey->sid . '/respondents');
+ }
+ }
+
/**
* Enketo API
* Converts the survey xml file to html for enketo to use
@@ -883,250 +1124,6 @@ public function _cb_survey_respondents_add_file_handle() {
}
- /**
- * Summary page to list the respondents associated to a given survey.
- * @param $sid
- *
- * Route - /survey/:sid/respondents/:page
- */
- public function survey_respondents($sid, $page = 1){
- $page = $page < 1 ? 1 : $page;
- $survey = $this->survey_model->get($sid);
- if (!$survey) {
- show_404();
- }
- else if (!has_permission('manage respondents any survey')) {
- show_403();
- }
-
- // Respondents to show per page.
- $respondents_pp = $this->config->item('aw_respondents_per_page');
- $this->load->library('pagination');
-
- // Prepare pagination.
- $this->pagination->initialize(array(
- 'base_url' => $survey->get_url_respondents(),
- 'use_page_numbers' => TRUE,
- 'uri_segment' => 4,
- 'total_rows' => $this->call_task_model->get_total_count($sid),
- 'per_page' => $respondents_pp,
- //'cur_tag_open' => '',
- //'cur_tag_close' => '',
- ));
-
- $respondents = $this->call_task_model->get_all_paginated($sid, $page, $respondents_pp);
-
- $messages = Status_msg::get();
- $data = array(
- 'survey' => $survey,
- 'respondents' => $respondents,
- //'messages' => $messages,
- 'messages' => $this->load->view('messages', array('messages' => $messages), TRUE)
- );
-
- $this->load->view('base/html_start');
- $this->load->view('navigation');
- $this->load->view('surveys/survey_respondents', $data);
- $this->load->view('base/html_end');
- }
-
- /**
- * Summary page to add respondents to a given survey.
- * @param $sid
- *
- * Route - /survey/:sid/respondents
- */
- public function survey_respondents_add($sid){
- $survey = $this->survey_model->get($sid);
- if (!$survey) {
- show_404();
- }
- else if (!has_permission('manage respondents any survey')) {
- show_403();
- }
-
- // Config data for the file upload.
- $file_upload_config = array(
- 'upload_path' => '/tmp/',
- 'allowed_types' => 'csv',
- 'file_name' => 'respondents_' . md5(microtime(true))
- );
-
- // Load needed libraries
- $this->load->library('upload', $file_upload_config);
-
- $this->form_validation->set_rules('survey_respondents_file', 'Respondents File', 'callback__cb_survey_respondents_add_file_handle');
- $this->form_validation->set_rules('survey_respondents_text', 'Respondents Text', 'xss_clean');
-
- // If no data submitted show the form.
- if ($this->form_validation->run() == FALSE) {
-
- $messages = Status_msg::get();
-
- $this->load->view('base/html_start');
- $this->load->view('navigation');
- $this->load->view('surveys/survey_respondents_add', array('survey' => $survey, 'messages' => $messages));
- $this->load->view('base/html_end');
- }
- else {
- // Initialize the respondents numbers list.
- $rows = explode("\n", $this->input->post('survey_respondents_text'));
- $textarea_lines = sizeof($rows);
- $respondents_numbers = array();
-
- // Read file, if any.
- $file = $this->input->post('survey_respondents_file');
-
- if (isset($file['full_path'])) {
- // Load CSVReader library.
- $this->load->helper('csvreader');
- $csv = new CSVReader();
- $csv->separator = ',';
- // We are merging the rows from csv to potential rows in the text area
- // this allows to verify everything in one pass.
- $rows = array_merge($rows, $csv->parse_file($file['full_path']));
- }
-
- $db_call_tasks = $this->call_task_model->get_all($sid);
-
- foreach ($rows as $line => $row) {
- // Silently skip empty rows.
- if (empty($row)) {
- continue;
- }
-
- // Prepare data.
- // If it's a row from the text area.
- if (!is_array($row)) {
- $context = 'textarea';
- $real_line = $line + 1;
- $row = trim($row);
- }
- // This is from the csv file.
- else {
- $context = 'CSV file';
- $real_line = ($line + 1) - $textarea_lines;
- // Make sure it's not a random CSV.
- if (isset($row[SURVEY_RESPONDENT_CSV_HEADER])) {
- $row = trim($row[SURVEY_RESPONDENT_CSV_HEADER]);
- }
- // Warn user.
- else {
- Status_msg::warning('Some data has been skipped. Make sure your column header is "' . SURVEY_RESPONDENT_CSV_HEADER .'".');
- }
- }
-
- // Common checks.
- // @todo check also if already present in the DB
- // hint: check $row against $object->number
- if (is_numeric($row)) {
-
- // Check db doubles.
- $is_double = FALSE;
- foreach ($db_call_tasks as $call_task) {
- if ($call_task->number == $row) {
- $is_double = TRUE;
- break;
- }
- }
-
- if ($is_double) {
- // Db Double.
- continue;
- }
- // END Check db doubles.
-
- if (!isset($respondents_numbers[$row])) {
- $respondents_numbers[$row] = 0;
- }
- $respondents_numbers[$row]++;
- }
- else {
- Status_msg::warning("Line #$real_line of the $context has been skipped as it does not appear to be a number.");
- }
- }
-
- // Store in session or issue error if.
- if (sizeof($respondents_numbers)) {
- $_SESSION['respondents_numbers'] = $respondents_numbers;
- }
- else {
- Status_msg::error('No usable numbers have been found in submitted data.');
- redirect('/survey/' . $survey->sid . '/respondents');
- }
-
- // Perform the redirect.
- redirect('/survey/' . $survey->sid . '/respondents/add/confirm');
- }
- }
-
- /**
- * Summary page to add respondents to a given survey.
- * @param $sid
- *
- * Route - /survey/:sid/respondents
- */
- public function survey_respondents_add_confirm($sid){
- $survey = $this->survey_model->get($sid);
- if (!$survey) {
- show_404();
- }
- else if (!has_permission('manage respondents any survey')) {
- show_403();
- }
-
- $messages = Status_msg::get();
- $data = array(
- 'survey' => $survey,
- 'messages' => $this->load->view('messages', array('messages' => $messages), TRUE),
- 'respondents_numbers' => array(),
- );
-
- // pass on the data to the view
- if (isset($_SESSION['respondents_numbers'])) {
- $data['respondents_numbers'] = array_keys($_SESSION['respondents_numbers']);
- }
-
- $this->form_validation->set_rules('survey_respondents_submit', '', 'required');
-
- // If no data submitted show the form.
- if ($this->form_validation->run() == FALSE) {
-
- $this->load->view('base/html_start');
- $this->load->view('navigation');
- $this->load->view('surveys/survey_respondents_confirm', $data);
- $this->load->view('base/html_end');
- }
- else {
-
- // create a call_task for each respondent number
- foreach ($_SESSION['respondents_numbers'] as $number => $qtd) {
- // Prepare survey data to construct a new survey_entity
- $call_task_data = array();
- // @todo find generic solution for the code below (int)
- $call_task_data['survey_sid'] = (int) $sid;
- $call_task_data['number'] = (string) $number;
-
- // Construct survey.
- $new_call_task = Call_task_entity::build($call_task_data);
-
- // Save survey.
- // Survey files can only be handled after the survey is saved.
- // TODO: Handle error during save.
- $this->call_task_model->save($new_call_task);
- }
-
- // User feedback.
- $numbers = sizeof($_SESSION['respondents_numbers']);
- Status_msg::success("Added $numbers entries to the call tasks of this survey.");
-
- unset($_SESSION['respondents_numbers']);
-
- // perform the redirect
- redirect('/survey/' . $survey->sid . '/respondents');
- }
- }
}
-
/* End of file survey.php */
-/* Location: ./application/controllers/survey.php */
+/* Location: ./application/controllers/survey.php */
\ No newline at end of file
diff --git a/application/controllers/user.php b/application/controllers/user.php
index 4c1bdf6..3999a7b 100644
--- a/application/controllers/user.php
+++ b/application/controllers/user.php
@@ -32,7 +32,6 @@ public function user_login() {
if ($this->form_validation->run() == FALSE) {
$this->load->view('base/html_start');
- $this->load->view('navigation');
$this->load->view('login');
$this->load->view('base/html_end');
}
@@ -58,13 +57,16 @@ public function user_logout() {
* /user
*/
public function user_profile($uid = null) {
+ // Profiles are disabled.
+ redirect();
+
// Viewing other user's profile is not a requirement.
// Viewing the current user profile requires the user
// to be logged in. It is not something to control through
// a permission.
if (is_logged()) {
$this->load->view('base/html_start');
- $this->load->view('navigation');
+ $this->load->view('components/navigation', array('active_menu' => 'users'));
$this->load->view('users/user_profile', array('user' => current_user()));
$this->load->view('base/html_end');
}
@@ -74,7 +76,7 @@ public function user_profile($uid = null) {
}
/**
- * Logout.
+ * Edit user by id.
* Route:
* /user/(:num)/edit
*/
@@ -120,7 +122,7 @@ protected function _edit_own_account() {
if ($this->form_validation->run() == FALSE) {
$this->load->view('base/html_start');
- $this->load->view('navigation');
+ $this->load->view('components/navigation', array('active_menu' => 'users'));
$this->load->view('users/user_form', array('user' => $user, 'action' => 'edit_own'));
$this->load->view('base/html_end');
}
@@ -151,7 +153,7 @@ protected function _edit_other_account($user) {
if ($this->form_validation->run() == FALSE) {
$this->load->view('base/html_start');
- $this->load->view('navigation');
+ $this->load->view('components/navigation', array('active_menu' => 'users'));
$this->load->view('users/user_form', array('user' => $user, 'action' => 'edit_other'));
$this->load->view('base/html_end');
}
@@ -198,7 +200,7 @@ protected function _add_account() {
if ($this->form_validation->run() == FALSE) {
$this->load->view('base/html_start');
- $this->load->view('navigation');
+ $this->load->view('components/navigation', array('active_menu' => 'users'));
$this->load->view('users/user_form', array('user' => NULL, 'action' => 'add'));
$this->load->view('base/html_end');
}
@@ -259,7 +261,6 @@ public function user_recover_password() {
if ($this->form_validation->run() == FALSE) {
$this->load->view('base/html_start');
- $this->load->view('navigation');
$this->load->view('users/user_recover_password');
$this->load->view('base/html_end');
}
@@ -271,15 +272,15 @@ public function user_recover_password() {
if ($hash) {
$this->load->library('email');
- // TODO: Email data. Use settings as much as possible.
- $this->email->from('aw-datacollection@airwolf.edispilf.org', 'Aw-datacollection Admin');
- $this->email->to('daniel.silva@flipside.org');
+ $this->email->from($this->config->item('aw_admin_email'), $this->config->item('aw_admin_name'));
+ $this->email->to($email);
- $this->email->subject('Password Recover');
+ $this->email->subject('Airwolf - Recover Password');
$this->email->message('Use the following link. ' . base_url('user/reset_password/' . $hash));
$this->email->send();
- // TODO: Message user. Check your email.
+
+ Status_msg::success('Please check your email for next steps.', TRUE);
redirect('login');
}
else {
@@ -305,7 +306,6 @@ public function user_reset_password($hash) {
if ($this->form_validation->run() == FALSE) {
$this->load->view('base/html_start');
- $this->load->view('navigation');
$this->load->view('users/user_reset_password');
$this->load->view('base/html_end');
}
@@ -317,11 +317,12 @@ public function user_reset_password($hash) {
if ($this->user_model->save($user)) {
$this->recover_password_model->invalidate($hash);
- // TODO: Message user. Login with your new password.
+
+ Status_msg::success('Password successfully changed. You can now login.', TRUE);
redirect('login');
}
else {
- show_error("Error saving your new password. Try again later.");
+ Status_msg::error("Error saving your new password. Try again later.");
}
}
@@ -354,7 +355,7 @@ public function users_list() {
$users = $this->user_model->get_all();
$this->load->view('base/html_start');
- $this->load->view('navigation');
+ $this->load->view('components/navigation', array('active_menu' => 'users'));
$this->load->view('users/user_list', array('users' => $users));
$this->load->view('base/html_end');
}
diff --git a/application/entities/survey_entity.php b/application/entities/survey_entity.php
index 9537646..81ee595 100644
--- a/application/entities/survey_entity.php
+++ b/application/entities/survey_entity.php
@@ -36,6 +36,20 @@ class Survey_entity extends Entity {
Survey_entity::STATUS_CLOSED => 'Closed',
Survey_entity::STATUS_CANCELED => 'Canceled',
);
+
+ /**
+ * Html classes for survey status.
+ *
+ * @var array
+ * @access public
+ * @static
+ */
+ static $statuses_html_classes = array(
+ Survey_entity::STATUS_DRAFT => 'status-draft',
+ Survey_entity::STATUS_OPEN => 'status-open',
+ Survey_entity::STATUS_CLOSED => 'status-closed',
+ Survey_entity::STATUS_CANCELED => 'status-canceled',
+ );
/********************************
********************************
@@ -264,6 +278,30 @@ public function get_url_edit() {
return base_url('survey/' . $this->sid . '/edit') ;
}
+ /**
+ * Returns the url to delete a survey.
+ * @access public
+ * @return string
+ */
+ public function get_url_delete() {
+ if ($this->sid == NULL) {
+ throw new Exception("Trying to get link for a non-existent survey.");
+ }
+ return base_url('survey/' . $this->sid . '/delete') ;
+ }
+
+ /**
+ * Returns the url to download survey file.
+ * @access public
+ * @return string
+ */
+ public function get_url_file($type) {
+ if ($this->sid == NULL) {
+ throw new Exception("Trying to get link for a non-existent survey.");
+ }
+ return base_url('survey/' . $this->sid . '/files/' . $type) ;
+ }
+
/**
* Returns the url to test run survey.
* @access public
@@ -432,7 +470,6 @@ public function has_xls() {
/**
* Returns the full path to the survey's xls file.
*
- *
* @return mixed
* If the survey has no file false is returned
*/
@@ -443,13 +480,38 @@ public function get_xls_full_path() {
/**
* Returns the full path to the survey's xls file.
*
- *
* @return mixed
* If the survey has no file false is returned
*/
public function get_xml_full_path() {
return $this->has_xml() ? $this->settings['file_loc'] . $this->files['xml'] : false;
}
+
+ /**
+ * Returns the survey status in human readable format.
+ *
+ * @return string
+ * The survey status in human readable format
+ */
+ public function get_status_label() {
+ if (!$this->status){
+ return NULL;
+ }
+ return Survey_entity::$statuses[$this->status];
+ }
+
+ /**
+ * Returns the survey status for use as html class.
+ *
+ * @return string
+ * The survey status for use as html class.
+ */
+ public function get_status_html_class($prefix = '') {
+ if (!$this->status){
+ return NULL;
+ }
+ return $prefix . Survey_entity::$statuses_html_classes[$this->status];
+ }
/**
* Checks if an agent is assigned to the survey.
diff --git a/application/helpers/general_utils_helper.php b/application/helpers/general_utils_helper.php
index fc4ebce..ef5e54e 100644
--- a/application/helpers/general_utils_helper.php
+++ b/application/helpers/general_utils_helper.php
@@ -103,6 +103,44 @@ function show_403() {
}
}
+if ( ! function_exists('verify_csrf_get')) {
+ /**
+ * CSRF verification for GET requests.
+ * This function verifies that the get request made to the page
+ * carries the CSRF token. If it not present it till throw the
+ * standard error.
+ * Assumes the param name is the token name.
+ */
+ function verify_csrf_get() {
+ $CI = get_instance();
+ $csrf_token_name = $CI->security->get_csrf_token_name();
+ $csrf_cookie_name = config_item('cookie_prefix') . config_item('csrf_cookie_name');
+ $link_token = $CI->input->get($csrf_token_name);
+
+ // Is token set?
+ if (!$link_token || !isset($_COOKIE[$csrf_cookie_name])){
+ $CI->security->csrf_show_error();
+ }
+
+ // Do the tokens match?
+ if ($link_token != $_COOKIE[$csrf_cookie_name]) {
+ $CI->security->csrf_show_error();
+ }
+
+ $CI->security->csrf_verify();
+ }
+}
+
+if ( ! function_exists('anchor_csrf')) {
+ function anchor_csrf($uri = '', $title = '', $attributes = '') {
+ $CI = get_instance();
+ $csrf_token_name = $CI->security->get_csrf_token_name();
+ $csrf_hash = $CI->security->get_csrf_hash();
+
+ $uri .= "?$csrf_token_name=$csrf_hash";
+ return anchor($uri, $title, $attributes);
+ }
+}
// ------------------------------------------------------------------------
diff --git a/application/helpers/status_msg_helper.php b/application/helpers/status_msg_helper.php
index 9d156e5..648735d 100644
--- a/application/helpers/status_msg_helper.php
+++ b/application/helpers/status_msg_helper.php
@@ -17,28 +17,41 @@ class Status_msg {
private static $userdata_key = 'status_msg';
/**
- * Stores success messages.
+ * Stores messages in the same order has they were set.
*/
- private static $success = array();
-
+ private static $messages = array();
+
/**
- * Stores warning messages.
+ * Sets a notice message.
+ *
+ * @static
*/
- private static $warning = array();
+ public static function set($msg, $level, $sticky = FALSE) {
+ self::$messages[] = array(
+ 'msg' => $msg,
+ 'level' => $level,
+ 'sticky' => $sticky,
+ 'time' => time(),
+ );
+ self::store();
+ }
/**
- * Stores error messages.
+ * Sets a notice message.
+ *
+ * @static
*/
- private static $error = array();
+ public static function notice($msg, $sticky = TRUE) {
+ self::set($msg, 'notice', $sticky);
+ }
/**
* Sets a success message.
*
* @static
*/
- public static function success($msg) {
- self::$success[] = $msg;
- self::store();
+ public static function success($msg, $sticky = FALSE) {
+ self::set($msg, 'success', $sticky);
}
/**
@@ -47,9 +60,8 @@ public static function success($msg) {
*
* @static
*/
- public static function warning($msg) {
- self::$warning[] = $msg;
- self::store();
+ public static function warning($msg, $sticky = TRUE) {
+ self::set($msg, 'warning', $sticky);
}
/**
@@ -58,9 +70,8 @@ public static function warning($msg) {
*
* @static
*/
- public static function error($msg) {
- self::$error[] = $msg;
- self::store();
+ public static function error($msg, $sticky = TRUE) {
+ self::set($msg, 'error', $sticky);
}
/**
@@ -69,11 +80,7 @@ public static function error($msg) {
*/
public static function store() {
$CI =& get_instance();
- $CI->session->set_userdata(self::$userdata_key, array(
- 'success' => self::$success,
- 'warning' => self::$warning,
- 'error' => self::$error
- ));
+ $CI->session->set_userdata(self::$userdata_key, self::$messages);
}
/**
diff --git a/application/models/survey_model.php b/application/models/survey_model.php
index cece610..4e92e6a 100644
--- a/application/models/survey_model.php
+++ b/application/models/survey_model.php
@@ -93,6 +93,8 @@ public function delete($sid) {
$result = $this->mongo_db
->where('sid', (int) $sid)
->delete(self::COLLECTION);
+
+ return $result !== FALSE ? TRUE : FALSE;
}
/**
diff --git a/application/views/base/footer_scripts.php b/application/views/base/footer_scripts.php
index fbb84cf..a723c54 100644
--- a/application/views/base/footer_scripts.php
+++ b/application/views/base/footer_scripts.php
@@ -1,9 +1,12 @@
+
+load->view('components/toast_messages'); ?>
+
+
-
-
\ No newline at end of file
+
+
\ No newline at end of file
diff --git a/application/views/base/head_styles.php b/application/views/base/head_styles.php
index 7966c16..7f5e365 100644
--- a/application/views/base/head_styles.php
+++ b/application/views/base/head_styles.php
@@ -3,4 +3,5 @@
+
\ No newline at end of file
diff --git a/application/views/base/html_end.php b/application/views/base/html_end.php
index 9741d8f..eddabed 100644
--- a/application/views/base/html_end.php
+++ b/application/views/base/html_end.php
@@ -1,3 +1,4 @@
+
load->view('base/footer_scripts') ?>