/** * @param $subject_id * @param $debug * determine completeness of all survey-containing events */ function events_completion($subject_id, $debug) { if (isset($subject_id)) { global $Proj, $project_id; $today = date("Y-m-d"); $fields = array(); $arms = get_arms(array_keys($Proj->eventsForms)); $baseline_event_id = $Proj->firstEventId; $enrollment_event_id = getNextEventId($baseline_event_id); $tx_duration = get_single_field($subject_id, $project_id, $enrollment_event_id, 'dm_suppdm_actarmdur', null); $tx_first_event = array_search_recursive($tx_duration . ' Weeks', $arms) !== false ? array_search_recursive($tx_duration . ' Weeks', $arms) : null; $survey_event_ids = isset($tx_first_event) ? array_merge(array($baseline_event_id), $Proj->getEventsByArmNum($arms[$tx_first_event]['arm_num'])) : array($baseline_event_id); foreach ($survey_event_ids AS $survey_event_id) { $survey_event_name = $Proj->getUniqueEventNames($survey_event_id); $survey_prefix = substr($survey_event_name, 0, strpos($survey_event_name, '_')); $fields[] = $survey_prefix . '_completed'; $fields[] = $survey_prefix . '_date'; $fields[] = $survey_prefix . '_startdate'; $fields[] = $survey_prefix . '_deadline'; } $data = REDCap::getData('array', $subject_id, $fields, $baseline_event_id); foreach ($survey_event_ids AS $survey_event_id) { $data_event_name = $Proj->getUniqueEventNames($survey_event_id); $prefix = substr($data_event_name, 0, strpos($data_event_name, '_')); $is_t_complete = is_t_complete($subject_id, $survey_event_id); $t_complete = $is_t_complete ? '1' : '0'; foreach ($data[$subject_id] AS $data_event_id => $data_event) { foreach ($data_event AS $key => $value) { /** * derive intra-event timing variables */ switch ($key) { case $prefix . '_completed': update_field_compare($subject_id, $project_id, $data_event_id, $t_complete, $value, $key, $debug); break; case $prefix . '_date': if ($value == '' && $is_t_complete) { update_field_compare($subject_id, $project_id, $data_event_id, $today, $value, $key, $debug); } break; default: break; } } } /** * derive inter-event timing variables */ $complete_value = get_single_field($subject_id, $project_id, $baseline_event_id, $prefix . '_completed', null); $start_date_value = get_single_field($subject_id, $project_id, $baseline_event_id, $prefix . '_startdate', null); $deadline_value = get_single_field($subject_id, $project_id, $baseline_event_id, $prefix . '_deadline', null); $missed_value = get_single_field($subject_id, $project_id, $baseline_event_id, $prefix . '_missed', null); $t_missed = $complete_value == '0' && $today > $deadline_value && isset($deadline_value) && $deadline_value != '' ? '1' : '0'; switch ($prefix) { case 't1': $t_base_date = get_single_field($subject_id, $project_id, $baseline_event_id, $prefix . '_date', null); $t_start_date = $t_base_date; $t_deadline_date = add_date($t_base_date, 89); break; default: $t_base_date = get_single_field($subject_id, $project_id, $enrollment_event_id, 'dm_rfstdtc', null); $t_start_date = add_date($t_base_date, ($arms[$data_event_name]['day_offset'] - $arms[$data_event_name]['offset_min'])); $t_deadline_date = add_date($t_base_date, ($arms[$data_event_name]['day_offset'] + $arms[$data_event_name]['offset_max']) - 1); break; } update_field_compare($subject_id, $project_id, $baseline_event_id, $t_complete, $complete_value, $prefix . '_completed', $debug); update_field_compare($subject_id, $project_id, $baseline_event_id, $t_missed, $missed_value, $prefix . '_missed', $debug); if (isset($t_base_date) && $t_base_date != '') { update_field_compare($subject_id, $project_id, $baseline_event_id, $t_start_date, $start_date_value, $prefix . '_startdate', $debug); update_field_compare($subject_id, $project_id, $baseline_event_id, $t_deadline_date, $deadline_value, $prefix . '_deadline', $debug); } } } }
/** * @param $record * @param $redcap_event_name * @param $instrument * @param $debug */ public static function code_terms($record, $redcap_event_name, $instrument, $debug) { global $Proj, $project_id, $tx_fragment_labels; $this_event_id = $Proj->getEventIdUsingUniqueEventName($redcap_event_name); switch ($instrument) { case 'ae_coding': $recode_llt = false; $recode_pt = true; $recode_soc = true; $prefix = 'ae'; /** * AE_AEMODIFY */ $fields = array("ae_aeterm", "ae_oth_aeterm", "ae_aemodify"); $data = REDCap::getData('array', $record, $fields, $this_event_id); code_llt($project_id, $record, $this_event_id, fix_case($data[$record][$this_event_id]['ae_aeterm']), fix_case($data[$record][$this_event_id]['ae_oth_aeterm']), $data[$record][$this_event_id]['ae_aemodify'], 'ae_aemodify', $debug, $recode_llt); if ($debug) { error_log("DEBUG: Coded AE_AEMODIFY {$data[$record][$this_event_id]['ae_aemodify']}: subject=$record, event=$this_event_id for AE {$data[$record][$this_event_id]['ae_aeterm']} - {$data[$record][$this_event_id]['ae_oth_aeterm']}"); } /** * PREFIX_AEDECOD * uses $tx_prefixes preset array */ $fields = array($prefix . "_aemodify", $prefix . "_aedecod"); $data = REDCap::getData('array', $record, $fields, $this_event_id); code_pt($project_id, $record, $this_event_id, $data[$record][$this_event_id][$prefix . "_aemodify"], $data[$record][$this_event_id][$prefix . "_aedecod"], $prefix . "_aedecod", $debug, $recode_pt); if ($debug) { error_log("DEBUG: Coded " . strtoupper($prefix) . "_AEDECOD {$data[$record][$this_event_id][$prefix . '_aedecod']}: subject=$record, event=$this_event_id for AEMODIFY {$data[$record][$this_event_id][$prefix . '_aemodify']}"); } /** * PREFIX_AEBODSYS * uses $tx_prefixes preset array */ $fields = array($prefix . "_aedecod", $prefix . "_aebodsys"); $data = REDCap::getData('array', $record, $fields, $this_event_id); code_bodsys($project_id, $record, $this_event_id, $data[$record][$this_event_id][$prefix . "_aedecod"], $data[$record][$this_event_id][$prefix . "_aebodsys"], $prefix . "_aebodsys", $debug, $recode_soc); if ($debug) { error_log("DEBUG: Coded SOC: subject=$record, event=$this_event_id for AE {$data[$record][$this_event_id][$prefix . "_aedecod"]}"); } unset($data); break; /** * ADVERSE EVENTS * ACTION: auto-code AE */ case 'adverse_events': $recode_llt = true; $recode_pt = true; $recode_soc = true; /** * AE_AEDECOD */ $fields = array("ae_aeterm", "ae_oth_aeterm", "ae_aemodify"); $data = REDCap::getData('array', $record, $fields, $this_event_id); code_llt($project_id, $record, $this_event_id, fix_case($data[$record][$this_event_id]['ae_aeterm']), fix_case($data[$record][$this_event_id]['ae_oth_aeterm']), $data[$record][$this_event_id]['ae_aemodify'], 'ae_aemodify', $debug, $recode_llt); if ($debug) { error_log("DEBUG: Coded AE_AEMODIFY {$data[$record][$this_event_id]['ae_aemodify']}: subject=$record, event=$this_event_id for AE {$data[$record][$this_event_id]['ae_aeterm']} - {$data[$record][$this_event_id]['ae_oth_aeterm']}"); } /** * AE_AEDECOD */ $fields = array("ae_aemodify", "ae_aedecod"); $data = REDCap::getData('array', $record, $fields, $this_event_id); code_pt($project_id, $record, $this_event_id, fix_case($data[$record][$this_event_id]['ae_aemodify']), $data[$record][$this_event_id]['ae_aedecod'], 'ae_aedecod', $debug, $recode_pt); if ($debug) { error_log("DEBUG: Coded AE_AEDECOD {$data[$record][$this_event_id]['ae_aedecod']}: subject=$record, event=$this_event_id for AE {$data[$record][$this_event_id]['ae_aemodify']}"); } /** * AE_AEBODSYS */ $fields = array("ae_aedecod", "ae_aebodsys"); $data = REDCap::getData('array', $record, $fields, $this_event_id); code_bodsys($project_id, $record, $this_event_id, $data[$record][$this_event_id]['ae_aedecod'], $data[$record][$this_event_id]['ae_aebodsys'], 'ae_aebodsys', $debug, $recode_soc); if ($debug) { error_log("DEBUG: Coded SOC: subject=$record, event=$this_event_id for AE {$data[$record][$this_event_id]['ae_aedecod']}"); } unset($data); break; /** * MEDICAL HISTORY * ACTION: auto-code MH */ case 'key_medical_history': $recode_llt = false; $recode_pt = true; $recode_soc = true; $mh_prefixes = array('othpsy', 'othca'); /** * MH_MHMODIFY */ foreach ($mh_prefixes AS $prefix) { $fields = array($prefix . "_oth_mhterm", $prefix . "_mhmodify"); $data = REDCap::getData('array', $record, $fields, $this_event_id); code_llt($project_id, $record, $this_event_id, fix_case($data[$record][$this_event_id][$prefix . "_oth_mhterm"]), '', $data[$record][$this_event_id][$prefix . "_mhmodify"], $prefix . "_mhmodify", $debug, $recode_llt); if ($debug) { error_log("DEBUG: Coded " . strtoupper($prefix) . "_MHMODIFY {$data[$record][$this_event_id][$prefix . "_mhmodify"]}: subject=$record, event=$this_event_id for MH {$data[$record][$this_event_id][$prefix . "_oth_mhterm"]}"); } /** * PREFIX_MHDECOD * uses $mh_prefixes preset array */ $fields = array($prefix . "_mhmodify", $prefix . "_mhdecod"); $data = REDCap::getData('array', $record, $fields, $this_event_id); code_pt($project_id, $record, $this_event_id, $data[$record][$this_event_id][$prefix . "_mhmodify"], $data[$record][$this_event_id][$prefix . "_mhdecod"], $prefix . "_mhdecod", $debug, $recode_pt); if ($debug) { error_log("DEBUG: Coded " . strtoupper($prefix) . "_MHDECOD {$data[$record][$this_event_id][$prefix . '_mhdecod']}: subject=$record, event=$this_event_id for MHMODIFY {$data[$record][$this_event_id][$prefix . '_mhmodify']}"); } /** * PREFIX_mhBODSYS * uses $mh_prefixes preset array */ $fields = array($prefix . "_mhdecod", $prefix . "_mhbodsys"); $data = REDCap::getData('array', $record, $fields, $this_event_id); code_bodsys($project_id, $record, $this_event_id, $data[$record][$this_event_id][$prefix . "_mhdecod"], $data[$record][$this_event_id][$prefix . "_mhbodsys"], $prefix . "_mhbodsys", $debug, $recode_soc); if ($debug) { error_log("DEBUG: Coded " . strtoupper($prefix) . "_MHBODSYS {$data[$record][$this_event_id][$prefix . "_mhbodsys"]}: subject=$record, event=$this_event_id for MHDECOD {$data[$record][$this_event_id][$prefix . "_mhdecod"]}"); } } unset($data); break; /** * EOT */ case 'early_discontinuation_eot': $recode_llt = true; $recode_pt = true; $recode_soc = true; /** * EOT_AEDECOD */ $data = REDCap::getData('array', $record, array("eot_suppds_ncmpae", "eot_oth_suppds_ncmpae", "eot_aemodify", "eot_dsterm"), $this_event_id); $ptdata = REDCap::getData('array', $record, array("eot_aemodify", "eot_aedecod"), $this_event_id); $soc_data = REDCap::getData('array', $record, array("eot_aedecod", "eot_aebodsys"), $this_event_id); foreach ($data[$record][$this_event_id] AS $event) { if ($event['eot_dsterm'] == 'ADVERSE_EVENT') { code_llt($project_id, $record, $this_event_id, fix_case($event['eot_suppds_ncmpae']), fix_case($event['eot_oth_suppds_ncmpae']), $event['eot_aemodify'], 'eot_aemodify', $debug, $recode_llt); if ($debug) { error_log("INFO (TESTING EOT): Coded EOT_AEMODIFY {$event['eot_aemodify']}: subject=$record, event=$this_event_id for AE {$event['eot_suppds_ncmpae']} - {$event['eot_oth_suppds_ncmpae']}"); } /** * AE_AEDECOD */ foreach ($ptdata[$record][$this_event_id] AS $ptevent) { code_pt($project_id, $record, $this_event_id, fix_case($ptevent['eot_aemodify']), $ptevent['eot_aedecod'], 'eot_aedecod', $debug, $recode_pt); if ($debug) { error_log("DEBUG: Coded EOT_AEDECOD {$ptevent['eot_aedecod']}: subject=$record, event=$this_event_id for AEMODIFY {$ptevent['eot_aemodify']}"); } } /** * EOT_AEBODSYS */ foreach ($soc_data[$record][$this_event_id] AS $soc_event) { code_bodsys($project_id, $record, $this_event_id, $soc_event['eot_aedecod'], $soc_event['eot_aebodsys'], 'eot_aebodsys', $debug, $recode_soc); if ($debug) { error_log("DEBUG: Coded SOC: subject=$record, event=$this_event_id for AE {$soc_event['eot_aedecod']}"); } } } } unset($data); unset($ptdata); unset($soc_data); break; /** * TX stop AEs */ case 'ribavirin_administration': case 'harvoni_administration': case 'ombitasvir_paritaprevir': case 'dasabuvir': case 'zepatier_administration': $recode_llt = true; $recode_pt = true; $recode_soc = true; $tx_prefix = array_search(substr($instrument, 0, strpos($instrument, '_')), $tx_fragment_labels); /** * AE_AEMODIFY */ $fields = array($tx_prefix . '_suppcm_cmncmpae', $tx_prefix . '_oth_suppcm_cmncmpae', $tx_prefix . '_aemodify'); $data = REDCap::getData('array', $record, $fields, $this_event_id); foreach ($data[$record][$this_event_id] AS $event) { code_llt($project_id, $record, $this_event_id, fix_case($event[$tx_prefix . '_suppcm_cmncmpae']), fix_case($event[$tx_prefix . '_oth_suppcm_cmncmpae']), $event[$tx_prefix . '_aemodify'], $tx_prefix . '_aemodify', $debug, $recode_llt); if ($debug) { error_log("DEBUG: Coded AE_AEMODIFY {$event[$tx_prefix . '_aemodify']}: subject=$record, event=$this_event_id for AE {$event[$tx_prefix . '_suppcm_cmncmpae']} - {$event[$tx_prefix . '_oth_suppcm_cmncmpae']}"); } } /** * AE_AEDECOD */ $fields = array($tx_prefix . '_aemodify', $tx_prefix . "_aedecod"); $data = REDCap::getData('array', $record, $fields, $this_event_id); foreach ($data[$record][$this_event_id] AS $event) { code_pt($project_id, $record, $this_event_id, fix_case($event[$tx_prefix . '_aemodify']), $event[$tx_prefix . '_aedecod'], $tx_prefix . '_aedecod', $debug, $recode_pt); if ($debug) { error_log("DEBUG: Coded AE_AEDECOD {$event[$tx_prefix . '_aedecod']}: subject=$record, event=$this_event_id for AE {$event[$tx_prefix . '_aemodify']}"); } } /** * AE_AEBODSYS */ $fields = array($tx_prefix . '_aedecod', $tx_prefix . '_aebodsys'); $data = REDCap::getData('array', $record, $fields, $this_event_id); foreach ($data[$record][$this_event_id] AS $event) { code_bodsys($project_id, $record, $this_event_id, $event[$tx_prefix . '_aedecod'], $event[$tx_prefix . '_aebodsys'], $tx_prefix . '_aebodsys', $debug, $recode_soc); if ($debug) { error_log("DEBUG: Coded SOC: subject=$record, event=$this_event_id for AE {$event[$tx_prefix . '_aedecod']}"); } } unset($data); break; /** * CONMEDS * ACTION: auto-code CONMEDS */ case 'conmeds': /** * CM_CMDECOD */ $recode_cm = true; $recode_llt = true; $recode_pt = true; $recode_soc = true; $recode_atc = true; $fields = array("cm_cmtrt", "cm_cmdecod", "cm_cmindc", "cm_oth_cmindc", "cm_suppcm_indcod"); $data = REDCap::getData('array', $record, $fields, $this_event_id); code_cm($project_id, $record, $this_event_id, $data[$record][$this_event_id], $debug, $recode_cm); /** * cm_suppcm_mktstat * PRESCRIPTION or OTC */ $fields = array("cm_cmdecod", "cm_suppcm_mktstat"); $data = REDCap::getData('array', $record, $fields, $this_event_id); foreach ($data as $subject_id => $subject) { foreach ($subject as $event_id => $event) { if (isset($event['cm_cmdecod']) && $event['cm_cmdecod'] != '') { update_field_compare($subject_id, $project_id, $event_id, get_conmed_mktg_status($event['cm_cmdecod']), $event['cm_suppcm_mktstat'], 'cm_suppcm_mktstat', $debug); if ($debug) { error_log("DEBUG: $subject_id Marketing Status = " . get_conmed_mktg_status($event['cm_cmdecod'])); } } } } /** * CM_SUPPCM_INDCOD */ $fields = array("cm_cmindc", "cm_oth_cmindc", "cm_suppcm_indcmodf"); $data = REDCap::getData('array', $record, $fields, $this_event_id); /** * re-code all nutritional support to nutritional supplement */ if ($data[$record][$this_event_id]['cm_oth_cmindc'] == 'Nutritional support') { $data[$record][$this_event_id]['cm_oth_cmindc'] = 'Nutritional supplement'; } code_llt($project_id, $record, $this_event_id, fix_case($data[$record][$this_event_id]['cm_cmindc']), fix_case($data[$record][$this_event_id]['cm_oth_cmindc']), $data[$record][$this_event_id]['cm_suppcm_indcmodf'], 'cm_suppcm_indcmodf', $debug, $recode_llt); if ($debug) { error_log("DEBUG: Coded INDC LLT: {} subject=$record, event=$this_event_id for INDICATION {$data[$record][$this_event_id]['cm_cmindc']}"); } /** * CM_SUPPCM_INDCOD */ $fields = array("cm_suppcm_indcmodf", "cm_suppcm_indcod"); $data = REDCap::getData('array', $record, $fields, $this_event_id); code_pt($project_id, $record, $this_event_id, $data[$record][$this_event_id]['cm_suppcm_indcmodf'], $data[$record][$this_event_id]['cm_suppcm_indcod'], 'cm_suppcm_indcod', $debug, $recode_pt); if ($debug) { error_log("DEBUG: Coded INDC PT: subject=$record, event=$this_event_id for INDICATION {$data[$record][$this_event_id]['cm_suppcm_indcod']}"); } /** * CM_SUPPCM_INDCSYS */ $fields = array("cm_suppcm_indcod", "cm_suppcm_indcsys"); $data = REDCap::getData('array', $record, $fields, $this_event_id); code_bodsys($project_id, $record, $this_event_id, $data[$record][$this_event_id]['cm_suppcm_indcod'], $data[$record][$this_event_id]['cm_suppcm_indcsys'], 'cm_suppcm_indcsys', $debug, $recode_soc); if ($debug) { error_log("DEBUG: Coded INDCSYS: subject=$record, event=$this_event_id for INDC {$data[$record][$this_event_id]['cm_suppcm_indcod']}"); } /** * CM_SUPPCM_ATCNAME * CM_SUPPCM_ATC2NAME */ $fields = array("cm_cmdecod", "cm_suppcm_atcname", "cm_suppcm_atc2name"); $data = REDCap::getData('array', $record, $fields, $this_event_id); code_atc($project_id, $record, $this_event_id, $data[$record][$this_event_id]['cm_cmdecod'], $data[$record][$this_event_id]['cm_suppcm_atcname'], $data[$record][$this_event_id]['cm_suppcm_atc2name'], $debug, $recode_atc); if ($debug) { error_log("DEBUG: Coded ATCs: subject=$record, event=$this_event_id for CONMED {$data[$record][$this_event_id]['cm_cmdecod']}"); } break; case 'transfusions': $recode_cm = true; $recode_llt = true; $recode_soc = true; $recode_atc = true; /** * XFSN_CMDECOD */ $fields = array("xfsn_cmtrt", "xfsn_cmdecod", "xfsn_cmindc", "xfsn_suppcm_indcod"); $data = REDCap::getData('array', $record, $fields, $this_event_id); code_cm($project_id, $record, $this_event_id, $data[$record][$this_event_id], $debug, $recode_cm); /** * XFSN_SUPPCM_INDCOD */ $fields = array("xfsn_cmindc", "xfsn_suppcm_indcod"); $data = REDCap::getData('array', $record, $fields, $this_event_id); code_llt($project_id, $record, $this_event_id, fix_case($data[$record][$this_event_id]['xfsn_cmindc']), fix_case($data[$record][$this_event_id]['xfsn_oth_cmindc']), $data[$record][$this_event_id]['xfsn_suppcm_indcod'], 'xfsn_suppcm_indcod', $debug, $recode_llt); if ($debug) { error_log("DEBUG: Coded XFSN INDC: subject=$record, event=$this_event_id for CONMED {$data[$record][$this_event_id]['xfsn_cmdecod']}"); } /** * XFSN_SUPPCM_INDCSYS */ $fields = array("xfsn_suppcm_indcod", "xfsn_suppcm_indcsys"); $data = REDCap::getData('array', $record, $fields, $this_event_id); code_bodsys($project_id, $record, $this_event_id, $data[$record][$this_event_id]['xfsn_suppcm_indcod'], $data[$record][$this_event_id]['xfsn_suppcm_indcsys'], 'xfsn_suppcm_indcsys', $debug, $recode_soc); if ($debug) { error_log("DEBUG: Coded XFSN INDCSYS: subject=$record, event=$this_event_id for INDC {$data[$record][$this_event_id]['xfsn_suppcm_indcod']}"); } /** * XFSN_SUPPCM_ATCNAME * XFSN_SUPPCM_ATC2NAME */ $fields = array("xfsn_cmdecod", "xfsn_suppcm_atcname", "xfsn_suppcm_atc2name"); $data = REDCap::getData('array', $record, $fields, $this_event_id); code_atc_xfsn($project_id, $record, $this_event_id, $data[$record][$this_event_id]['xfsn_cmdecod'], $data[$record][$this_event_id]['xfsn_suppcm_atcname'], $data[$record][$this_event_id]['xfsn_suppcm_atc2name'], $debug, $recode_atc); if ($debug) { error_log("DEBUG: Coded XFSN ATCs: subject=$record, event=$this_event_id for CONMED {$data[$record][$this_event_id]['xfsn_cmdecod']}"); } unset($data); break; case 'mh_coding': $recode_llt = false; $recode_pt = true; $recode_soc = true; $mh_prefixes = array('othpsy', 'othca'); /** * MH_MHMODIFY */ foreach ($mh_prefixes AS $prefix) { $fields = array($prefix . "_oth_mhterm", $prefix . "_mhmodify"); $data = REDCap::getData('array', $record, $fields, $this_event_id); code_llt($project_id, $record, $this_event_id, fix_case($data[$record][$this_event_id][$prefix . "_oth_mhterm"]), '', $data[$record][$this_event_id][$prefix . "_mhmodify"], $prefix . "_mhmodify", $debug, $recode_llt); if ($debug) { error_log("DEBUG: Coded " . strtoupper($prefix) . "_MHMODIFY {$data[$record][$this_event_id][$prefix . "_mhmodify"]}: subject=$record, event=$this_event_id for MH {$data[$record][$this_event_id][$prefix . "_oth_mhterm"]}"); } /** * PREFIX_MHDECOD * uses $mh_prefixes preset array */ $fields = array($prefix . "_mhmodify", $prefix . "_mhdecod"); $data = REDCap::getData('array', $record, $fields, $this_event_id); code_pt($project_id, $record, $this_event_id, $data[$record][$this_event_id][$prefix . "_mhmodify"], $data[$record][$this_event_id][$prefix . "_mhdecod"], $prefix . "_mhdecod", $debug, $recode_pt); if ($debug) { error_log("DEBUG: Coded " . strtoupper($prefix) . "_MHDECOD {$data[$record][$this_event_id][$prefix . '_mhdecod']}: subject=$record, event=$this_event_id for MHMODIFY {$data[$record][$this_event_id][$prefix . '_mhmodify']}"); } /** * PREFIX_mhBODSYS * uses $mh_prefixes preset array */ $fields = array($prefix . "_mhdecod", $prefix . "_mhbodsys"); $data = REDCap::getData('array', $record, $fields, $this_event_id); code_bodsys($project_id, $record, $this_event_id, $data[$record][$this_event_id][$prefix . "_mhdecod"], $data[$record][$this_event_id][$prefix . "_mhbodsys"], $prefix . "_mhbodsys", $debug, $recode_soc); if ($debug) { error_log("DEBUG: Coded " . strtoupper($prefix) . "_MHBODSYS {$data[$record][$this_event_id][$prefix . "_mhbodsys"]}: subject=$record, event=$this_event_id for MHDECOD {$data[$record][$this_event_id][$prefix . "_mhdecod"]}"); } } unset($data); break; case 'cm_coding': $recode_llt = false; $recode_pt = true; $recode_soc = true; $recode_atc = false; $recode_cm = true; /** * CM_CMDECOD */ $fields = array("cm_cmtrt", "cm_cmdecod", "cm_cmindc", "cm_oth_cmindc", "cm_suppcm_indcod"); $data = REDCap::getData('array', $record, $fields, $this_event_id); code_cm($project_id, $record, $this_event_id, $data[$record][$this_event_id], $debug, $recode_cm); if ($debug) { error_log("DEBUG: Coded CONMED: subject=$record, event=$this_event_id for CMTRT {$data[$record][$this_event_id]['cm_cmtrt']}"); } /** * cm_suppcm_mktstat * PRESCRIPTION or OTC */ $fields = array("cm_cmdecod", "cm_suppcm_mktstat"); $data = REDCap::getData('array', $record, $fields, $this_event_id); foreach ($data as $subject_id => $subject) { foreach ($subject as $event_id => $event) { if (isset($event['cm_cmdecod']) && $event['cm_cmdecod'] != '') { update_field_compare($subject_id, $project_id, $event_id, get_conmed_mktg_status($event['cm_cmdecod']), $event['cm_suppcm_mktstat'], 'cm_suppcm_mktstat', $debug); if ($debug) { error_log("DEBUG: $subject_id Marketing Status = " . get_conmed_mktg_status($event['cm_cmdecod'])); } } } } /** * CM_SUPPCM_INDCOD */ $fields = array("cm_cmindc", "cm_oth_cmindc", "cm_suppcm_indcmodf"); $data = REDCap::getData('array', $record, $fields, $this_event_id); /** * re-code all nutritional support to nutritional supplement */ if ($data[$record][$this_event_id]['cm_oth_cmindc'] == 'Nutritional support') { $data[$record][$this_event_id]['cm_oth_cmindc'] = 'Nutritional supplement'; } code_llt($project_id, $record, $this_event_id, fix_case($data[$record][$this_event_id]['cm_cmindc']), fix_case($data[$record][$this_event_id]['cm_oth_cmindc']), $data[$record][$this_event_id]['cm_suppcm_indcmodf'], 'cm_suppcm_indcmodf', $debug, $recode_llt); if ($debug) { error_log("DEBUG: Coded INDC LLT: {} subject=$record, event=$this_event_id for INDICATION {$data[$record][$this_event_id]['cm_cmindc']}"); } /** * CM_SUPPCM_INDCOD */ $fields = array("cm_suppcm_indcmodf", "cm_suppcm_indcod"); $data = REDCap::getData('array', $record, $fields, $this_event_id); code_pt($project_id, $record, $this_event_id, $data[$record][$this_event_id]['cm_suppcm_indcmodf'], $data[$record][$this_event_id]['cm_suppcm_indcod'], 'cm_suppcm_indcod', $debug, $recode_pt); if ($debug) { error_log("DEBUG: Coded INDC PT: subject=$record, event=$this_event_id for INDICATION {$data[$record][$this_event_id]['cm_suppcm_indcod']}"); } /** * CM_SUPPCM_INDCSYS */ $fields = array("cm_suppcm_indcod", "cm_suppcm_indcsys"); $data = REDCap::getData('array', $record, $fields, $this_event_id); code_bodsys($project_id, $record, $this_event_id, $data[$record][$this_event_id]['cm_suppcm_indcod'], $data[$record][$this_event_id]['cm_suppcm_indcsys'], 'cm_suppcm_indcsys', $debug, $recode_soc); if ($debug) { error_log("DEBUG: Coded INDCSYS: subject=$record, event=$this_event_id for INDC {$data[$record][$this_event_id]['cm_suppcm_indcod']}"); } /** * CM_SUPPCM_ATCNAME * CM_SUPPCM_ATC2NAME */ $fields = array("cm_cmdecod", "cm_suppcm_atcname", "cm_suppcm_atc2name"); $data = REDCap::getData('array', $record, $fields, $this_event_id); code_atc_soc($project_id, $record, $this_event_id, $data[$record][$this_event_id]['cm_cmdecod'], $data[$record][$this_event_id]['cm_suppcm_atcname'], $data[$record][$this_event_id]['cm_suppcm_atc2name'], $debug, $recode_atc); if ($debug) { error_log("DEBUG: Coded ATCs: subject=$record, event=$this_event_id for CONMED {$data[$record][$this_event_id]['cm_cmdecod']}"); } /** * XFSN_CMDECOD */ $fields = array("xfsn_cmtrt", "xfsn_cmdecod", "xfsn_cmindc", "xfsn_suppcm_indcod"); $data = REDCap::getData('array', $record, $fields, $this_event_id); foreach ($data AS $subject_id => $subject) { foreach ($subject AS $event_id => $event) { if (isset($event['xfsn_cmtrt']) && $event['xfsn_cmtrt'] != '') { $med = array(); $med_result = db_query("SELECT DISTINCT drug_coded FROM _target_xfsn_coding WHERE drug_name = '" . prep($event['xfsn_cmtrt']) . "'"); if ($med_result) { $med = db_fetch_assoc($med_result); if (isset($med['drug_coded']) && $med['drug_coded'] != '') { update_field_compare($subject_id, $project_id, $event_id, $med['drug_coded'], $event['xfsn_cmdecod'], 'xfsn_cmdecod', $debug); } } if ($debug) { error_log("DEBUG: Coded Transfusion: subject=$subject_id, event=$event_id for CMTRT {$event['xfsn_cmtrt']}"); } } else { update_field_compare($subject_id, $project_id, $event_id, '', $event['xfsn_cmdecod'], 'xfsn_cmdecod', $debug); } } } /** * XFSN_SUPPCM_INDCOD */ $fields = array("xfsn_cmindc", "xfsn_suppcm_indcod"); $data = REDCap::getData('array', $record, $fields, $this_event_id); code_llt($project_id, $record, $this_event_id, fix_case($data[$record][$this_event_id]['xfsn_cmindc']), fix_case($data[$record][$this_event_id]['xfsn_oth_cmindc']), $data[$record][$this_event_id]['xfsn_suppcm_indcod'], 'xfsn_suppcm_indcod', $debug, $recode_llt); if ($debug) { error_log("DEBUG: Coded XFSN INDC: subject=$record, event=$this_event_id for CONMED {$data[$record][$this_event_id]['xfsn_cmdecod']}"); } /** * XFSN_SUPPCM_INDCSYS */ $fields = array("xfsn_suppcm_indcod", "xfsn_suppcm_indcsys"); $data = REDCap::getData('array', $record, $fields, $this_event_id); code_bodsys($project_id, $record, $this_event_id, $data[$record][$this_event_id]['xfsn_suppcm_indcod'], $data[$record][$this_event_id]['xfsn_suppcm_indcsys'], 'xfsn_suppcm_indcsys', $debug, $recode_soc); if ($debug) { error_log("DEBUG: Coded XFSN INDCSYS: subject=$record, event=$this_event_id for INDC {$data[$record][$this_event_id]['xfsn_suppcm_indcod']}"); } /** * XFSN_SUPPCM_ATCNAME * XFSN_SUPPCM_ATC2NAME */ $fields = array("xfsn_cmdecod", "xfsn_suppcm_atcname", "xfsn_suppcm_atc2name"); $data = REDCap::getData('array', $record, $fields, $this_event_id); code_atc_xfsn($project_id, $record, $this_event_id, $data[$record][$this_event_id]['xfsn_cmdecod'], $data[$record][$this_event_id]['xfsn_suppcm_atcname'], $data[$record][$this_event_id]['xfsn_suppcm_atc2name'], $debug, $recode_atc); if ($debug) { error_log("DEBUG: Coded XFSN ATCs: subject=$record, event=$this_event_id for CONMED {$data[$record][$this_event_id]['xfsn_cmdecod']}"); } unset($data); break; case 'ex_coding': $recode_pt = true; $recode_soc = true; $prefix = 'eot'; /** * PREFIX_AEDECOD * uses $tx_prefixes preset array */ $fields = array($prefix . "_aemodify", $prefix . "_aedecod"); $data = REDCap::getData('array', $record, $fields, $this_event_id); code_pt($project_id, $record, $this_event_id, $data[$record][$this_event_id][$prefix . "_aemodify"], $data[$record][$this_event_id][$prefix . "_aedecod"], $prefix . "_aedecod", $debug, $recode_pt); if ($debug) { error_log("DEBUG: Coded " . strtoupper($prefix) . "_AEDECOD {$data[$record][$this_event_id][$prefix . '_aedecod']}: subject=$record, event=$this_event_id for AEMODIFY {$data[$record][$this_event_id][$prefix . '_aemodify']}"); } /** * PREFIX_AEBODSYS * uses $tx_prefixes preset array */ $fields = array($prefix . "_aedecod", $prefix . "_aebodsys"); $data = REDCap::getData('array', $record, $fields, $this_event_id); code_bodsys($project_id, $record, $this_event_id, $data[$record][$this_event_id][$prefix . "_aedecod"], $data[$record][$this_event_id][$prefix . "_aebodsys"], $prefix . "_aebodsys", $debug, $recode_soc); if ($debug) { error_log("DEBUG: Coded SOC: subject=$record, event=$this_event_id for AE {$data[$record][$this_event_id][$prefix . "_aedecod"]}"); } unset($data); break; default: break; } }
/** * debug */ $debug = $_GET['debug'] ? (bool)$_GET['debug'] : false; /** * includes */ $base_path = dirname(dirname(dirname(__FILE__))); require_once $base_path . "/redcap_connect.php"; require_once $base_path . '/plugins/includes/functions.php'; require APP_PATH_CLASSES . "Message.php"; /** * restricted use */ $allowed_pids = array('38'); REDCap::allowProjects($allowed_pids); Kint::enabled($debug); /** * initialize variables */ $item_count = 0; $today = date('Y-m-d'); $rows = ''; /** * query target_email_actions for any actions that haven't yet been digested. * digest and send them */ $actions_result = db_query("SELECT DISTINCT * FROM target_email_actions WHERE (digest_date IS NULL OR digest_date = '') AND project_id = '$project_id' ORDER BY redcap_data_access_group ASC, abs(record) ASC"); if ($actions_result) { while ($actions_row = db_fetch_assoc($actions_result)) { $item_count++;
/** * restrict access to one or more pids */ $allowed_pids = array('38'); REDCap::allowProjects($allowed_pids); /** * project metadata */ global $Proj; /** * initialize variables */ $plugin_title = "Derive Treatment Started (trt_suppex_txstat)"; /** * plugin title */ echo "<h3>$plugin_title</h3>"; /** * MAIN LOOP */ $fields = array("dm_rfstdtc", "trt_suppex_txstat"); $data = REDCap::getData('array', $subjects, $fields, $Proj->firstEventId); if ($debug && $subjects != '') { show_var($data); } foreach ($data AS $subject_id => $subject) { foreach ($subject AS $event_id => $event) { $started = $event['dm_rfstdtc'] == '' ? 'N' : 'Y'; update_field_compare($subject_id, $project_id, $event_id, $started, $event['trt_suppex_txstat'], 'trt_suppex_txstat', $debug); } }
<?php /* * Longitudinal Reports Plugin * Luke Stevens, Murdoch Childrens Research Institute https://www.mcri.edu.au * Version date 16-Nov-2015 */ require_once dirname(__FILE__) . '/config.php'; // Validate id if (!isset($_POST['report_id'])) { exit('0'); } $report_id = $_POST['report_id']; $success = LongitudinalReports::deleteReport($report_id); if ($success) { REDCap::logEvent("Delete longitudinal report", "report_id = {$report_id}"); } print $success === false ? '0' : '1';
$stmt->close(); return -3; } // mgGetNumberOfKeyValuePairsForRecord $scrf = PAGE_FULL; /*****************************************************************************/ if (!array_key_exists("records_to_delete_textarea", $_POST)) { // Present the form if (!array_key_exists("pid", $_GET) or !($proj_id = $_GET["pid"])) { exit("<b>Missing project number</b>. Make sure your URL appends \"<tt>?pid=123</tt>\" where <i>123</i> is your project number."); } $scrf .= "?pid=" . $proj_id; if (!SUPER_USER) { // Get array of user privileges for a single user in project (will have username as array key) $this_user = USERID; $rights = REDCap::getUserRights($this_user); // If $rights returns NULL, then user does not have access to this project if (empty($this_user) or empty($rights)) { exit("User {$this_user} does NOT have access to this project."); } // Check if user can delete records if (!$rights[$this_user]['record_delete']) { exit("User {$this_user} does NOT have permission to delete records from this project."); } } // echo "<p>The project is $proj_id.</p>" ?> <p>Please paste in a list record numbers to delete, one per-line or separated by spaces. </p> <p>Note that there is <i>no</i> confirmation of deletion! Once you click the DELETE RECORDS button below your supplied records will be <b>permanently deleted</b> from this project, so please double-check your list before proceeding. </p> <form action="
public static function set_dag($record, $instrument, $debug) { global $project_id; /** * SET Data Access Group based upon dm_usubjid prefix */ $fields = array('dm_usubjid'); $data = REDCap::getData('array', $record, $fields); foreach ($data AS $subject) { foreach ($subject AS $event_id => $event) { if ($event['dm_usubjid'] != '') { /** * find which DAG this subject belongs to */ $site_prefix = substr($event['dm_usubjid'], 0, 3) . '%'; $dag_query = "SELECT group_id, group_name FROM redcap_data_access_groups WHERE project_id = '$project_id' AND group_name LIKE '$site_prefix'"; $dag_result = db_query($dag_query); if ($dag_result) { $dag = db_fetch_assoc($dag_result); if (isset($dag['group_id'])) { /** * For each event in project for this subject, determine if this subject_id has been added to its appropriate DAG. If it hasn't, make it so. * First, we need a list of events for which this subject has data */ $subject_events_query = "SELECT DISTINCT event_id FROM redcap_data WHERE project_id = '$project_id' AND record = '$record' AND field_name = '" . $instrument . "_complete'"; $subject_events_result = db_query($subject_events_query); if ($subject_events_result) { while ($subject_events_row = db_fetch_assoc($subject_events_result)) { if (isset($subject_events_row['event_id'])) { $_GET['event_id'] = $subject_events_row['event_id']; // for logging /** * The subject has data in this event_id * does the subject have corresponding DAG assignment? */ $has_event_data_query = "SELECT DISTINCT event_id FROM redcap_data WHERE project_id = '$project_id' AND record = '$record' AND event_id = '" . $subject_events_row['event_id'] . "' AND field_name = '__GROUPID__'"; $has_event_data_result = db_query($has_event_data_query); if ($has_event_data_result) { $has_event_data = db_fetch_assoc($has_event_data_result); if (!isset($has_event_data['event_id'])) { /** * Subject does not have a matching DAG assignment for this data * construct proper matching __GROUPID__ record and insert */ $insert_dag_query = "INSERT INTO redcap_data SET record = '$record', event_id = '" . $subject_events_row['event_id'] . "', value = '" . $dag['group_id'] . "', project_id = '$project_id', field_name = '__GROUPID__'"; if (!$debug) { if (db_query($insert_dag_query)) { target_log_event($insert_dag_query, 'redcap_data', 'insert', $record, $dag['group_name'], 'Assign record to Data Access Group (' . $dag['group_name'] . ')'); } else { error_log("SQL INSERT FAILED: " . db_error() . "\n"); echo db_error() . "\n"; } } else { show_var($insert_dag_query); error_log('(TESTING) NOTICE: ' . $insert_dag_query); } } db_free_result($has_event_data_result); } } } db_free_result($subject_events_result); } } db_free_result($dag_result); } } } } }
public function renderTestRow($id, $label, $selectedRecord, $selectedEvent) { // Make a dropdown that contains all record_ids. $data = REDCap::getData('array', NULL, REDCap::getRecordIdField()); //error_log("data: ".print_r($data,true)); foreach ($data as $record_id => $arr) { $record_id_options[$record_id] = $record_id; } // Get all Events $events = REDCap::getEventNames(TRUE, FALSE); $row = RCView::tr(array(), RCView::td(array('class' => 'td1'), self::insertHelp('test')) . RCView::td(array('class' => 'td2'), "<label for='test-{$id}'><b>{$label}:</b></label>") . RCView::td(array('class' => 'td3'), RCView::span(array(), "Test logic using " . REDCap::getRecordIdField() . ":" . RCView::select(array('id' => "test_record-{$id}", 'name' => "test_record-{$id}", 'class' => "tbi x-form-text x-form-field", 'style' => 'height:20px;border:0px;', 'onchange' => "testLogic('{$id}');"), $record_id_options, $selectedRecord)) . RCView::span(array('style' => 'display:' . (REDCap::isLongitudinal() ? 'inline;' : 'none;')), " of event " . RCView::select(array('id' => "test_event-{$id}", 'name' => "test_event-{$id}", 'class' => "tbi x-form-text x-form-field", 'style' => 'height:20px;border:0px;', 'onchange' => "testLogic('{$id}');"), $events, $selectedEvent)) . RCView::span(array(), RCView::button(array('class' => 'jqbuttonmed ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only', 'onclick' => 'testLogic("' . $id . '");', 'style' => 'margin:0px 10px;'), 'Test') . RCView::span(array('id' => 'result-' . $id))))); return $row; }
/** * restricted use */ $allowed_pids = array('26'); REDCap::allowProjects($allowed_pids); global $Proj; Kint::enabled($debug); /** * APRI */ $uln = 40; $chem_fields = array('chem_lbdtc', 'ast_lbstresn'); $cbc_fields = array('cbc_lbdtc', 'plat_lbstresn', 'apri_lborres'); $cbc_data = REDCap::getData('array', '', $cbc_fields); foreach ($cbc_data AS $subject_id => $subject) { $chem_events = array(); $chem_data = REDCap::getData('array', $subject_id, $chem_fields); foreach ($subject AS $event_id => $event) { $apri_score = ''; if ($event['cbc_lbdtc'] != '' && $event['plat_lbstresn'] != '' && is_numeric($event['plat_lbstresn'])) { foreach ($chem_data AS $chem_subject) { foreach ($chem_subject AS $chem_event) { if ($chem_event['chem_lbdtc'] != '' && $chem_event['ast_lbstresn'] != '' && $chem_event['chem_lbdtc'] == $event['cbc_lbdtc'] && is_numeric($chem_event['ast_lbstresn'])) { $apri_score = (string)round(((($chem_event['ast_lbstresn'] / $uln) / $event['plat_lbstresn']) * 100), 2); } } } } update_field_compare($subject_id, $project_id, $event_id, $apri_score, $event['apri_lborres'], 'apri_lborres', $debug); } }
* initialize variables */ $timer_start = microtime(true); $monitor_name = $_POST['monitor_name']; $table_csv = ""; $export_filename = "TRANSPLANT_MONITORING_" . strtoupper($monitor_name); /** * get sim/sof data */ $fields = array('sim_cmstdtc', 'sof_cmstdtc'); $data = REDCap::getData('array', '', $fields); /** * get TX history data */ $hist_fields = array("dm_rfstdtc", "dm_rfendtc", "livr_mhoccur"); $hist_data = REDCap::getData('array', '', $hist_fields, $first_event_id); $subject_sql = "SELECT data.record AS subjid, IF (demo.username IS NULL, 'N', 'Y') AS demo_locker, IF (eot.username IS NULL, 'N', 'Y') AS eot_locker, dsterm.value AS eot_status, geno.value AS genotype FROM (SELECT DISTINCT record, project_id FROM `redcap_data`) data LEFT OUTER JOIN (SELECT * FROM `redcap_locking_data` WHERE form_name = 'demographics') demo ON data.record = demo.record AND data.project_id = demo.project_id LEFT OUTER JOIN (SELECT * FROM `redcap_locking_data` WHERE form_name = 'early_discontinuation_eot') eot ON data.record = eot.record AND data.project_id = eot.project_id LEFT OUTER JOIN (SELECT * FROM redcap_data WHERE field_name = 'eot_dsterm') dsterm ON data.record = dsterm.record AND data.project_id = dsterm.project_id LEFT OUTER JOIN (SELECT * FROM redcap_data WHERE field_name = 'hcvgt_lborres') geno ON data.record = geno.record AND data.project_id = geno.project_id WHERE data.project_id = '$project_id'";
if ($rbv_event['rib_cmstdtc'] != '') { if (!$has_rbv) { $regimen = $regimen . ' RBV'; $has_rbv = true; } } } } if ($sim && $sof) { $wk4_start_obj = new DateTime($event['dm_rfstdtc']); $wk4_start_obj->add(new DateInterval('P20D')); $wk4_start_date = $wk4_start_obj->format('Y-m-d'); $wk4_end_obj = new DateTime($event['dm_rfstdtc']); $wk4_end_obj->add(new DateInterval('P36D')); $wk4_end_date = $wk4_end_obj->format('Y-m-d'); $hcv_data = REDCap::getData('array', $subject_id, $hcv_fields); foreach ($hcv_data AS $hcv_subject) { foreach ($hcv_subject AS $hcv_event) { if (($wk4_start_date < $hcv_event['hcv_lbdtc'] && $hcv_event['hcv_lbdtc'] < $wk4_end_date) && ($hcv_event['hcv_lbstresn'] != '' || $hcv_event['hcv_supplb_hcvdtct'] != '')) { $data_row = array(); if ($debug) { show_var($subject_id, 'SUBJECT', 'blue'); show_var($regimen, 'REGIMEN'); show_var($event['dm_rfstdtc'], 'START DATE'); show_var($wk4_start_date, '4WK START'); show_var($hcv_event['hcv_lbdtc'], 'HCVRNA DATE'); show_var($wk4_end_date, '4WK END'); show_var($hcv_event['hcv_lbstresn'], 'QUANT'); show_var($hcv_event['hcv_supplb_hcvdtct'], 'DETECT'); } $data_row['subjid'] = $subject_id;
$misc_fields = array('hcvgt_lborres', 'hcvgt_s_lborres', 'hcv_suppfa_hcvout', 'cirr_suppfa_cirrstat', 'cirr_suppfa_decomp', 'dcp_mhoccur', 'livr_mhoccur'); foreach ($misc_fields AS $field) { if ($field != 'hcvgt_s_lborres') { $header_array[] = quote_wrap(get_element_label($field)); } } $misc_data = REDCap::getData('array', $subjects, $misc_fields, $Proj->firstEventId); $egfr_fields = array('egfr_lborres', 'egfr_im_lborres', 'egfr_lbblfl', 'egfr_im_lbblfl'); $egfr_data = REDCap::getData('array', $subjects, $egfr_fields); foreach ($egfr_fields AS $field) { if ($field == 'egfr_lborres') { $header_array[] = quote_wrap('Baseline ' . get_element_label($field)); } } $hcvrna_fields = array('hcv_lbblfl', 'hcv_lbstresn', 'hcv_im_lbblfl', 'hcv_im_lbstresn'); $hcvrna_data = REDCap::getData('array', $subjects, $hcvrna_fields); foreach ($hcvrna_fields AS $field) { if ($field == 'hcv_lbstresn') { $header_array[] = quote_wrap('Baseline ' . get_element_label($field)); } } /** * MAIN */ foreach ($data AS $subject_id => $subject) { d($subject[$Proj->firstEventId]['dm_usubjid']); /** * SUBJECT-LEVEL vars */ $data_row = array(); $regimens = array();
foreach ($fields AS $field) { $header_array[] = quote_wrap($Proj->metadata[$field]['element_label']); } $data = REDCap::getData('array', '', $fields, $Proj->firstEventId); $treatment_exp_fields = array('pegifn_mhoccur', 'pegifn_suppmh_response', 'triple_mhoccur', 'triple_suppmh_cmdaa', 'triple_suppmh_response', 'nopegifn_mhoccur', 'daa_mhoccur', 'daa_suppmh_failtype', 'daa_oth_suppmh_failtype'); foreach ($treatment_exp_fields AS $field) { $header_array[] = quote_wrap($Proj->metadata[$field]['element_label']); } $treatment_exp_data = REDCap::getData('array', '', $treatment_exp_fields, $Proj->firstEventId); $misc_fields = array('hcvgt_lborres', 'hcvgt_s_lborres', 'hcv_suppfa_hcvout', 'cirr_suppfa_cirrstat', 'dcp_mhoccur', 'livr_mhoccur'); foreach ($misc_fields AS $field) { if ($field != 'hcvgt_s_lborres') { $header_array[] = quote_wrap($Proj->metadata[$field]['element_label']); } } $misc_data = REDCap::getData('array', '', $misc_fields, $Proj->firstEventId); /** * MAIN */ foreach ($data AS $subject_id => $subject) { d($subject[$Proj->firstEventId]['dm_usubjid']); /** * SUBJECT-LEVEL vars */ $data_row = array(); $regimens = array(); /** * MAIN EVENT LOOP */ foreach ($subject AS $event_id => $event) { $data_row[get_element_label('dm_usubjid')] = $event['dm_usubjid'] != '' ? quote_wrap($event['dm_usubjid']) : quote_wrap('--');
require_once $base_path . '/plugins/includes/functions.php'; require_once APP_PATH_DOCROOT . '/Config/init_project.php'; require_once APP_PATH_DOCROOT . '/ProjectGeneral/header.php'; /** * restrict use of this plugin to the appropriate project */ $allowed_pid = '26'; REDCap::allowProjects($allowed_pid); Kint::enabled($debug); global $Proj; $baseline_event_id = $Proj->firstEventId; /** * let's bring this into the 21st century */ $fields = array('dm_subjid', 'dm_usubjid'); $data = REDCap::getData('array', $subjects, $fields, $baseline_event_id); foreach ($data AS $subject) { foreach ($subject AS $event_id => $event) { if ($event['dm_usubjid'] != '') { /** * find which DAG this subject belongs to */ $site_prefix = substr($event['dm_usubjid'], 0, 3) . '%'; $dag_query = "SELECT group_id, group_name FROM redcap_data_access_groups WHERE project_id = '$project_id' AND group_name LIKE '$site_prefix'"; $dag_result = db_query($dag_query); if ($dag_result) { $dag = db_fetch_assoc($dag_result); if (isset($dag['group_id'])) { /** * For each event in project for this subject, determine if this subject_id has been added to its appropriate DAG. If it hasn't, make it so. * First, we need a list of events for which this subject has data
db_query($sql);*/ // Loop through report_ids and set new report_order $report_order = 1; $import = array(); foreach ($new_report_ids as $this_report_id) { /* $sql = "update redcap_reports set report_order = ".$report_order++." where project_id = $project_id and report_id = $this_report_id"; db_query($sql);*/ $rpt = array(); $rpt['report_id'] = $this_report_id; $rpt['report_order'] = $report_order++; $import[] = $rpt; } // Deal with orphaned report_ids added simultaneously by other user while this user reorders foreach ($append_report_ids as $this_report_id) { /* $sql = "update redcap_reports set report_order = ".$report_order++." where project_id = $project_id and report_id = $this_report_id"; db_query($sql);*/ $rpt = array(); $rpt['report_id'] = $this_report_id; $rpt['report_order'] = $report_order++; $import[] = $rpt; } $success = LongitudinalReports::save($import); if (!$success) { exit('0'); } // Logging REDCap::logEvent("Reorder longitudinal reports", "report_id = " . $_POST['report_ids']); // Return Value: If there are some extra reports that exist that are not currently in the list, then refresh the user's page print !empty($append_report_ids) ? '2' : '1';
/** * GET DATA FOR RECORDS * [@param int $project_id - (optional) Manually supplied project_id for this project.] * @param string $returnFormat - Default 'array'. Return record data in specified format (array, csv, json, xml). * @param string/array $records - if provided as a string, will convert to an array internally. * @param string/array $fields - if provided as a string, will convert to an array internally. * @param string/array $events - if provided as a string, will convert to an array internally. * @param string/array $groups - if provided as a string, will convert to an array internally. * @param bool $combine_checkbox_values is only an option for $returnFormat csv, json, and xml, in which it determines whether * checkbox option values are returned as multiple fields with triple underscores or as a combined single field with all *checked* * options as comma-delimited (e.g., "1,3,4" if only choices 1, 3, and 4 are checked off). * NOTE: 'array' returnFormat will always have event_id as 2nd key and will always have checkbox options as a sub-array * for each given checkbox field. */ public static function getData() { global $salt, $reserved_field_names, $lang, $user_rights, $redcap_version, $datetime_format; // Get function arguments $args = func_get_args(); // Make sure we have a project_id if (!is_numeric($args[0]) && !defined("PROJECT_ID")) { throw new Exception('No project_id provided!'); } // If first parameter is numerical, then assume it is $project_id and that second parameter is $returnFormat if (is_numeric($args[0])) { $project_id = $args[0]; $returnFormat = isset($args[1]) ? $args[1] : 'array'; $records = isset($args[2]) ? $args[2] : array(); $fields = isset($args[3]) ? $args[3] : array(); $events = isset($args[4]) ? $args[4] : array(); $groups = isset($args[5]) ? $args[5] : array(); $combine_checkbox_values = isset($args[6]) ? $args[6] : false; $outputDags = isset($args[7]) ? $args[7] : false; $outputSurveyFields = isset($args[8]) ? $args[8] : false; $filterLogic = isset($args[9]) ? $args[9] : false; $outputAsLabels = isset($args[10]) ? $args[10] : false; $outputCsvHeadersAsLabels = isset($args[11]) ? $args[11] : false; $hashRecordID = isset($args[12]) ? $args[12] : false; $dateShiftDates = isset($args[13]) ? $args[13] : false; $dateShiftSurveyTimestamps = isset($args[14]) ? $args[14] : false; $sortArray = isset($args[15]) ? $args[15] : array(); $removeLineBreaksInValues = isset($args[16]) ? $args[16] : false; $replaceFileUploadDocId = isset($args[17]) ? $args[17] : false; $returnIncludeRecordEventArray = isset($args[18]) ? $args[18] : false; $orderFieldsAsSpecified = isset($args[19]) ? $args[19] : false; $outputSurveyIdentifier = isset($args[20]) ? $args[20] : $outputSurveyFields; $outputCheckboxLabel = isset($args[21]) ? $args[21] : false; $outputScheduleDates = isset($args[22]) ? $args[22] : false; $outputSurveyUrls = isset($args[23]) ? $args[23] : false; // Instantiate object containing all project information $Proj = new Project($project_id); $longitudinal = $Proj->longitudinal; $table_pk = $Proj->table_pk; } else { $project_id = PROJECT_ID; $returnFormat = isset($args[0]) ? $args[0] : 'array'; $records = isset($args[1]) ? $args[1] : array(); $fields = isset($args[2]) ? $args[2] : array(); $events = isset($args[3]) ? $args[3] : array(); $groups = isset($args[4]) ? $args[4] : array(); $combine_checkbox_values = isset($args[5]) ? $args[5] : false; $outputDags = isset($args[6]) ? $args[6] : false; $outputSurveyFields = isset($args[7]) ? $args[7] : false; $filterLogic = isset($args[8]) ? $args[8] : false; $outputAsLabels = isset($args[9]) ? $args[9] : false; $outputCsvHeadersAsLabels = isset($args[10]) ? $args[10] : false; $hashRecordID = isset($args[11]) ? $args[11] : false; $dateShiftDates = isset($args[12]) ? $args[12] : false; $dateShiftSurveyTimestamps = isset($args[13]) ? $args[13] : false; $sortArray = isset($args[14]) ? $args[14] : array(); $removeLineBreaksInValues = isset($args[15]) ? $args[15] : false; $replaceFileUploadDocId = isset($args[16]) ? $args[16] : false; $returnIncludeRecordEventArray = isset($args[17]) ? $args[17] : false; $orderFieldsAsSpecified = isset($args[18]) ? $args[18] : false; $outputSurveyIdentifier = isset($args[19]) ? $args[19] : $outputSurveyFields; $outputCheckboxLabel = isset($args[20]) ? $args[20] : false; $outputScheduleDates = isset($args[21]) ? $args[21] : false; $outputSurveyUrls = isset($args[22]) ? $args[22] : false; // Get existing values since Project object already exists in global scope global $Proj, $longitudinal, $table_pk; } // Get current memory limit in bytes $memory_limit = str_replace("M", "", ini_get('memory_limit')) * 1024 * 1024; // Set array of valid $returnFormat values $validReturnFormats = array('html', 'csv', 'xml', 'json', 'array'); // Set array of valid MC field types (don't include "checkbox" because it gets dealt with on its own) $mc_field_types = array("radio", "select", "yesno", "truefalse", "sql"); // If $returnFormat is not valid, set to default 'csv' if (!in_array($returnFormat, $validReturnFormats)) { $returnFormat = 'csv'; } // Cannot use $outputAsLabels for 'array' output if ($returnFormat == 'array') { $outputAsLabels = false; } // Can only use $outputCsvHeadersAsLabels for 'csv' output if ($returnFormat != 'csv') { $outputCsvHeadersAsLabels = false; } // If surveys are not enabled, then set $outputSurveyFields to false if (!$Proj->project['surveys_enabled'] || empty($Proj->surveys)) { $outputSurveyFields = false; } // Use for replacing strings in labels (if needed) $orig = array("\"", "\r\n", "\n", "\r"); $repl = array("'", " ", " ", ""); // Determine if we should apply sortArray $applySortFields = is_array($sortArray) && !empty($sortArray); ## Set all input values // Get unique event names (with event_id as key) $unique_events = $Proj->getUniqueEventNames(); // Create array of formatted event labels if ($longitudinal && $outputAsLabels) { $event_labels = array(); foreach (array_keys($unique_events) as $this_event_id) { $event_labels[$this_event_id] = str_replace($orig, $repl, strip_tags(label_decode($Proj->eventInfo[$this_event_id]['name_ext']))); } } // If $fields is a string, convert to array if (!is_array($fields) && $fields != null) { $fields = array($fields); } // If $fields is empty, replace it with array of ALL fields. $removeTablePk = false; if (empty($fields)) { foreach (array_keys($Proj->metadata) as $this_field) { // Make sure field is not a descriptive field (because those will never have data) if ($Proj->metadata[$this_field]['element_type'] != 'descriptive') { $fields[] = $this_field; } } $checkFieldNameEachLoop = true; } else { // If only returning the record-event array (as the subset record list for a report), // then make sure the record ID is added, or else it'll break some things downstream (not ideal solution but works as quick patch). // Also do this for longitudinal projects because if we don't, it might not pull data for an entire event if data doesn't exist // for any fields here except the record ID field. NOTE: Make sure we remove the record ID field in the end though (so it doesn't get returned if (($Proj->longitudinal || $returnIncludeRecordEventArray) && !in_array($Proj->table_pk, $fields)) { $fields = array_merge(array($Proj->table_pk), $fields); $removeTablePk = true; } // Validate all field names and order fields according to metadata field order $field_order = array(); foreach ($fields as $this_key => $this_event_field) { $this_field = LongitudinalReports::getFieldFromEventField($this_event_field); // Make sure field exists AND is not a descriptive field (because those will never have data) if (isset($Proj->metadata[$this_field]) && $Proj->metadata[$this_field]['element_type'] != 'descriptive') { // Put in array for sorting $field_order[] = $Proj->metadata[$this_field]['field_order']; } else { // Remove any invalid field names unset($fields[$this_key]); } } // Sort fields by metadata field order (unless passing a flag to prevent reordering) if (!$orderFieldsAsSpecified) { array_multisort($field_order, SORT_NUMERIC, $fields); } unset($field_order); // If we're querying more than 25% of the project's fields, then don't put field names in query but check via PHP each loop. $checkFieldNameEachLoop = count($fields) / count($Proj->metadata) > 0.25; } // Create array of fields with field name as key $fieldsKeys = array_fill_keys($fields, true); // If $events is a string, convert to array if (!is_array($events) && $events != null) { $events = array($events); } // If $events is empty, replace it with array of ALL fields. if (empty($events)) { $events = array_keys($Proj->eventInfo); } else { // If $events has unique event name (instead of event_ids), then convert all to event_ids $events_temp = array(); foreach ($events as $this_key => $this_event) { // If numeric, validate event_id if (is_numeric($this_event)) { if (!isset($Proj->eventInfo[$this_event])) { // Remove invalid event_id unset($events[$this_key]); } else { // Valid event_id $events_temp[] = $this_event; } } else { // Get array key of unique event name provided $event_id_key = array_search($this_event, $unique_events); if ($event_id_key !== false) { // Valid event_id $events_temp[] = $event_id_key; } } } // Now swap out $events_temp for $events $events = $events_temp; unset($events_temp); } // Get array of all DAGs $allDags = $Proj->getUniqueGroupNames(); // Validate DAGs if (empty($allDags)) { // If no DAGs exist, then automatically set array as empty $groups = array(); // Automatically set $outputDags as false (in case was set to true mistakenly) $outputDags = false; } else { // If $groups is a string, convert to array if (!is_array($groups) && $groups != null) { $groups = array($groups); } // If $groups is not empty, replace it with array of ALL data access group IDs. if (!empty($groups)) { // If $groups has unique group name (instead of group_ids), then convert all to group_ids $groups_temp = array(); foreach ($groups as $this_key => $this_group) { // If numeric, validate group_id if (is_numeric($this_group)) { if (!isset($allDags[$this_group])) { // Check to see if its really the unique group name (and not the group_id) // LS Patched: https://iwg.devguard.com/trac/redcap/changeset/7747#file0 $group_id_key = array_search($this_group, $allDags); if ($group_id_key !== false) { // Valid group_id $groups_temp[] = $group_id_key; } else { // Remove invalid group_id unset($groups[$this_key]); } } else { // Valid group_id $groups_temp[] = $this_group; } } else { // Get array key of unique group name provided $group_id_key = array_search($this_group, $allDags); if ($group_id_key !== false) { // Valid group_id $groups_temp[] = $group_id_key; } } } // Now swap out $groups_temp for $groups $groups = $groups_temp; unset($groups_temp); } } ## RECORDS // If $records is a string, convert to array if (!is_array($records) && $records != null) { $records = array($records); } // If $records is empty, replace it with array of ALL records. $recordsEmpty = false; $recordCount = null; if (empty($records)) { $records = self::getRecordList($project_id); // Set flag that $records was originally passed as empty $recordsEmpty = true; $checkRecordNameEachLoop = true; } else { // If we're querying more than 25% of the project's records, then don't put field names in query but check via PHP each loop. if ($recordCount == null) { $recordCount = self::getRecordCount(); } $checkRecordNameEachLoop = count($records) / $recordCount > 0.25; } // Create array of fields with field name as key $recordsKeys = array_fill_keys($records, true); ## DAG RECORDS: If pulling data for specific DAGs, get list of records in DAGs specified and replace $records with them $hasDagRecords = false; if (!empty($groups)) { // Collect all DAG records into array $dag_records = array(); $sql = "select distinct record from redcap_data where project_id = {$project_id}\n\t\t\t\t\tand field_name = '__GROUPID__' and value in (" . prep_implode($groups) . ")"; if (!$checkRecordNameEachLoop) { $sql .= " and record in (" . prep_implode($records) . ")"; } $q = db_query($sql); while ($row = db_fetch_assoc($q)) { // If we need to validate the record name in each loop, then check. if ($checkRecordNameEachLoop && !isset($recordsKeys[$row['record']])) { continue; } // Add to array $dag_records[] = $row['record']; } // Set flag if returned some DAG records $hasDagRecords = !empty($dag_records); // Replace $records array $records = $dag_records; unset($dag_records); // If we're querying more than 25% of the project's records, then don't put field names in query but check via PHP each loop. if ($recordCount == null) { $recordCount = self::getRecordCount(); } $checkRecordNameEachLoop = count($records) / $recordCount > 0.25; // Create array of fields with field name as key $recordsKeys = array_fill_keys($records, true); } ## APPLY FILTERING LOGIC: Get records-events where filter logic is true $filterResults = false; $filterReturnedEmptySet = false; if ($filterLogic != '') { // Get array of applicable record-events (only pass $project_id if already passed explicitly to getData) $record_events_filtered = self::applyFilteringLogic($filterLogic, $records, is_numeric($args[0]) ? $project_id : null); $filterResults = $record_events_filtered !== false; // If logic returns zero record/events, then manually set $records to ''/blank if ($filterResults) { if (empty($record_events_filtered)) { $records = array(''); $checkRecordNameEachLoop = false; $filterReturnedEmptySet = true; } else { // Replace headers $records = array_keys($record_events_filtered); // If we're querying more than 25% of the project's records, then don't put field names in query but check via PHP each loop. if ($recordCount == null) { $recordCount = self::getRecordCount(); } $checkRecordNameEachLoop = count($records) / $recordCount > 0.25; // Create array of fields with field name as key $recordsKeys = array_fill_keys($records, true); } } } ## SORTING IN REPORTS: If the sort fields are NOT in $fields (i.e. should be returned as data), // then temporarily add them to $fields and then remove them later when performing sorting. if ($applySortFields) { $sortArrayRemoveFromData = array(); foreach (array_keys($sortArray) as $this_field) { if (!in_array($this_field, $fields)) { $sortArrayRemoveFromData[] = $fields[] = $this_field; } } } ## PIPING (only for exporting labels OR for displaying reports) $piping_receiver_fields = array(); $do_label_piping = false; if ($outputAsLabels || $returnFormat == 'html') { // If any dropdowns, radios, or checkboxes are using piping in their option labels, then get data for those and then inject them $piping_transmitter_fields = $piping_record_data = array(); foreach ($fields as $this_field) { $this_field = LongitudinalReports::getFieldFromEventField($this_field); if (in_array($Proj->metadata[$this_field]['element_type'], array('dropdown', 'select', 'radio', 'checkbox'))) { $this_field_enum = $Proj->metadata[$this_field]['element_enum']; // If has at least one left and right square bracket if ($this_field_enum != '' && strpos($this_field_enum, '[') !== false && strpos($this_field_enum, ']') !== false) { // If has at least one field piped $these_piped_fields = array_keys(getBracketedFields($this_field_enum, true, true, true)); if (!empty($these_piped_fields)) { $piping_receiver_fields[] = $this_field; $piping_transmitter_fields = array_merge($piping_transmitter_fields, $these_piped_fields); } } } } if (!empty($piping_receiver_fields)) { // Get data for piping fields $piping_record_data = self::getData('array', $records, $piping_transmitter_fields); // Remove unneeded variables unset($piping_transmitter_fields, $potential_piping_fields); // Set flag $do_label_piping = true; } } ## GATHER DEFAULT VALUES // Get default values for all records (all fields get value '', except Form Status and checkbox fields get value 0) $default_values = $mc_choice_labels = array(); $prev_form = null; $fieldsNoEventRef = array(); foreach ($fields as $this_field) { //LongitudinalReports: make array of field names without event ref for reading from redcap_data $this_field = LongitudinalReports::getFieldFromEventField($this_field); if (array_search($this_field, $fieldsNoEventRef) === false) { $fieldsNoEventRef[] = $this_field; } // Get field's field type $field_type = $Proj->metadata[$this_field]['element_type']; // If exporting labels for multiple choice questions, store codes/labels in array for later use when replacing if ($outputAsLabels && ($field_type == 'checkbox' || in_array($field_type, $mc_field_types))) { if ($field_type == "yesno") { $mc_choice_labels[$this_field] = parseEnum("1, Yes \\n 0, No"); } elseif ($field_type == "truefalse") { $mc_choice_labels[$this_field] = parseEnum("1, True \\n 0, False"); } else { $enum = $field_type == "sql" ? getSqlFieldEnum($Proj->metadata[$this_field]['element_enum']) : $Proj->metadata[$this_field]['element_enum']; foreach (parseEnum($enum) as $this_value => $this_label) { // Decode (just in case) $this_label = html_entity_decode($this_label, ENT_QUOTES); // Replace double quotes with single quotes $this_label = str_replace("\"", "'", $this_label); // Replace line breaks with two spaces $this_label = str_replace("\r\n", " ", $this_label); // Add to array $mc_choice_labels[$this_field][$this_value] = $this_label; } } } // Loop through all designated events so that each event foreach (array_keys($Proj->eventInfo) as $this_event_id) { // If event_id isn't in list of event_ids provided, then skip if (!in_array($this_event_id, $events)) { continue; } // Get the form_name of this field $this_form = $Proj->metadata[$this_field]['form_name']; $current_event_field = "[{$Proj->getUniqueEventNames($this_event_id)}][{$this_field}]"; if (array_search($current_event_field, $fields) !== false || $this_field == $Proj->table_pk && $this_event_id == $Proj->firstEventId) { // If we're starting a new survey, then add its Timestamp field as the first field in the instrument if ($outputSurveyFields && $this_field != $table_pk && isset($Proj->forms[$this_form]['survey_id'])) { $current_event_field = "[{$Proj->getUniqueEventNames($this_event_id)}][{$this_field}_timestamp]"; $default_values[$current_event_field] = ''; //$default_values[$this_event_id][$this_form.'_timestamp'] = ''; } // If longitudinal, is this form designated for this event $validFormEvent = !$longitudinal || $longitudinal && in_array($this_form, $Proj->eventsForms[$this_event_id]); // Check a checkbox or Form Status field if ($Proj->isCheckbox($this_field)) { // Loop through all choices and set each as 0 foreach (array_keys(parseEnum($Proj->metadata[$this_field]['element_enum'])) as $choice) { // Set default value as 0 (unchecked) if (!$validFormEvent || $outputAsLabels && $outputCheckboxLabel) { $default_values[$current_event_field][$choice] = ''; //$default_values[$this_event_id][$this_field][$choice] = ''; } elseif ($outputAsLabels) { $default_values[$current_event_field][$choice] = 'Unchecked'; //$default_values[$this_event_id][$this_field][$choice] = 'Unchecked'; } else { $default_values[$current_event_field][$choice] = '0'; //$default_values[$this_event_id][$this_field][$choice] = '0'; } } } elseif ($this_field == $this_form . "_complete") { // Set default Form Status as 0 if (!$validFormEvent) { $default_values[$current_event_field] = ''; //$default_values[$this_event_id][$this_field] = ''; } elseif ($outputAsLabels) { $default_values[$current_event_field] = 'Incomplete'; //$default_values[$this_event_id][$this_field] = 'Incomplete'; } else { $default_values[$current_event_field] = '0'; //$default_values[$this_event_id][$this_field] = '0'; } } else { // Set as '' $default_values[$current_event_field] = ''; //$default_values[$this_event_id][$this_field] = ''; // If this is the Record ID field and we're exporting DAG names and/or survey fields, them add them. // If the Record ID field is not included in the report, then add DAG names and/or survey fields if not already added. if ($this_field == $table_pk || !in_array($table_pk, $fields)) { // DAG field if ($outputDags && !isset($default_values['redcap_data_access_group'])) { $default_values['redcap_data_access_group'] = ''; } if ($outputSurveyIdentifier && !isset($default_values['redcap_survey_identifier'])) { // Survey Identifier field $default_values['redcap_survey_identifier'] = ''; // Survey Timestamp field (first instrument only - for other instruments, it's doing this same thing above in the loop) // if ($prev_form == null && isset($Proj->forms[$this_form]['survey_id'])) { // $default_values[$this_event_id][$this_form.'_timestamp'] = ''; // } } // Event schedule dates selected if (is_array($outputScheduleDates) && count($outputScheduleDates) > 0) { foreach ($outputScheduleDates as $outputDateEventId) { $default_values["[{$Proj->getUniqueEventNames($outputDateEventId)}][___schedule_date]"] = ''; } } // Survey URLs selected if (is_array($outputSurveyUrls) && count($outputSurveyUrls) > 0) { foreach ($outputSurveyUrls as $outputSurveyEventIdSurveyId) { //Event id/survey form stored as pipe-separated pair e.g. 2365|my_survey $eventsurvey = explode('|', $outputSurveyEventIdSurveyId); $eventRef = $Proj->getUniqueEventNames($eventsurvey[0]); $default_values["[{$eventRef}][{$eventsurvey['1']}___url]"] = ''; } } } } } // Set for next loop $prev_form = $this_form; } } ## QUERY DATA TABLE // Set main query $sql = "select record, event_id, field_name, value from redcap_data\n\t\t\t\twhere project_id = " . $project_id . " and record != ''"; if (!empty($events)) { $sql .= " and event_id in (" . prep_implode($events) . ")"; } if (!$checkFieldNameEachLoop && !empty($fields)) { // $sql .= " and field_name in (" . prep_implode($fields) . ")"; $sql .= " and field_name in (" . prep_implode($fieldsNoEventRef) . ")"; } if (!$checkRecordNameEachLoop && !empty($records)) { $sql .= " and record in (" . prep_implode($records) . ")"; } // If we are to return records for specific DAG(s) but those DAGs contain no records, then cause the query to return nothing. if (!$hasDagRecords && !empty($groups)) { $sql .= " and 1 = 2"; } // Order query results by record name if constant has been defined if (defined("EXPORT_WRITE_TO_FILE")) { $sql .= " order by record"; } //print "<br><b>MySQL Error:</b> ".db_error()."<br><b>Query:</b> $sql<br><br>"; // Use unbuffered query method $q = db_query($sql, null, MYSQLI_USE_RESULT); // Return database query error to super users if (defined('SUPER_USER') && SUPER_USER && db_error() != '') { print "<br><b>MySQL Error:</b> " . db_error() . "<br><b>Query:</b> {$sql}<br><br>"; } // Set flag is record ID field is a display field $recordIdInFields = in_array($Proj->table_pk, $fields); // Remove unnecessary things for memory usage purposes // unset($fields, $events); // Set intial values $num_rows_returned = 0; $event_id = 0; $record = ""; $record_data = array(); $days_to_shift = array(); $record_data_tmp_line = array(); $record_line = 1; // If writing data to a file instead to memory, create temp file if (defined("EXPORT_WRITE_TO_FILE")) { $record_data_tmp_file = tmpfile(); } // Loop through data one record at a time while ($row = db_fetch_assoc($q)) { // If value is blank, then skip if ($row['value'] == '') { continue; } // If we need to validate the record name in each loop, then check. if ($checkRecordNameEachLoop && !isset($recordsKeys[$row['record']])) { continue; } // If we need to validate the field name in each loop, then check. if ($checkFieldNameEachLoop && !isset($fieldsKeys["[{$Proj->getUniqueEventNames($row['event_id'])}][{$row['field_name']}]"])) { continue; } // // If filtering the results using a logic string, then skip this record-event if doesn't match valid logic // if ($filterResults && !isset($record_events_filtered[$row['record']][$row['event_id']])) continue; // Add initial default data for this record-event if (!isset($record_data[$row['record']])) { // [$row['event_id']])) { /* // If we're close to running out of memory, then set contstant and call this method recursively // to start over and write data to file instead of to memory (to allow full data export w/o hitting memory limits). if (!defined("EXPORT_WRITE_TO_FILE") && memory_get_usage() >= $memory_limit*0.8) { // Define the constant define("EXPORT_WRITE_TO_FILE", true); // Unset variables to clear up memory unset($record_data, $records, $recordsKeys, $fieldsKeys, $record_events_filtered); // Close the unbuffered query db_free_result($q); // Call this function with constant defined to start over while writing data to file return call_user_func_array('Records::getData', $args); } elseif (defined("EXPORT_WRITE_TO_FILE") && $event_id > 0) { // Add data to file and clear from array fwrite($record_data_tmp_file, serialize(array($record=>array($event_id=>$record_data[$record][$event_id])))."\n"); // Add this to record line $record_data_tmp_line[$record][$event_id] = $record_line++; // Clear array for next record-event $record_data = array(); } */ // Add default data // $record_data[$row['record']][$row['event_id']] = $default_values[$row['event_id']]; $record_data[$row['record']] = $default_values; // Get date shift amount for this record (if applicable) if ($dateShiftDates) { $days_to_shift[$row['record']] = self::get_shift_days($row['record'], $Proj->project['date_shift_max'], $Proj->project['__SALT__']); } } // Decode the value $row['value'] = html_entity_decode($row['value'], ENT_QUOTES); // Set values for this loop $event_id = $row['event_id']; $record = $row['record']; // Add the value into the array (double check to make sure the event_id still exists) // - but only if it is an event/field we're interested in for Longitudinal Report if (isset($unique_events[$event_id])) { $current_event_field = "[{$Proj->getUniqueEventNames($event_id)}][{$row['field_name']}]"; if (array_search($current_event_field, $fields) !== false || $row['field_name'] == $Proj->table_pk && $event_id == $Proj->firstEventId) { // Get field's field type $field_type = $Proj->metadata[$row['field_name']]['element_type']; if ($field_type == 'checkbox') { // Make sure that this checkbox option still exists //if (isset($default_values[$event_id][$row['field_name']][$row['value']])) { if (isset($default_values[$current_event_field][$row['value']])) { // Add checkbox field value if ($outputAsLabels) { // If using $outputCheckboxLabel API flag, then output the choice label if ($outputCheckboxLabel) { // Get MC option label $this_mc_label = $mc_choice_labels[$row['field_name']][$row['value']]; // PIPING (if applicable) if ($do_label_piping && in_array($row['field_name'], $piping_receiver_fields)) { $this_mc_label = strip_tags(Piping::replaceVariablesInLabel($this_mc_label, $record, $event_id, $piping_record_data)); } // Add option label //$record_data[$record][$event_id][$row['field_name']][$row['value']] = $this_mc_label; $record_data[$record][$current_event_field][$row['value']] = $this_mc_label; } else { //$record_data[$record][$event_id][$row['field_name']][$row['value']] = 'Checked'; $record_data[$record][$current_event_field][$row['value']] = 'Checked'; } } else { //$record_data[$record][$event_id][$row['field_name']][$row['value']] = '1'; $record_data[$record][$current_event_field][$row['value']] = '1'; } } } else { // Non-checkbox field value // When outputting labels for MULTIPLE CHOICE questions (excluding checkboxes), add choice labels to answers_labels if ($outputAsLabels && isset($mc_choice_labels[$row['field_name']])) { // Get MC option label $this_mc_label = $mc_choice_labels[$row['field_name']][$row['value']]; // PIPING (if applicable) if ($do_label_piping && in_array($row['field_name'], $piping_receiver_fields)) { $this_mc_label = strip_tags(Piping::replaceVariablesInLabel($this_mc_label, $record, $event_id, $piping_record_data)); } // Add option label //$record_data[$record][$event_id][$row['field_name']] = $this_mc_label; $record_data[$record][$current_event_field] = $this_mc_label; } else { // Shift all date[time] fields, when applicable if ($dateShiftDates && $field_type == 'text' && (substr($Proj->metadata[$row['field_name']]['element_validation_type'], 0, 8) == 'datetime' || in_array($Proj->metadata[$row['field_name']]['element_validation_type'], array('date', 'date_ymd', 'date_mdy', 'date_dmy')))) { //$record_data[$record][$event_id][$row['field_name']] = Records::shift_date_format($row['value'], $days_to_shift[$record]); $record_data[$record][$current_event_field] = Records::shift_date_format($row['value'], $days_to_shift[$record]); } elseif ($replaceFileUploadDocId && $field_type == 'file') { //$record_data[$record][$event_id][$row['field_name']] = '[document]'; $record_data[$record][$current_event_field] = '[document]'; } else { // Check if we should replace any line breaks with spaces or double quotes with single quotes if ($removeLineBreaksInValues) { $row['value'] = str_replace($orig, $repl, $row['value']); } // Add value //$record_data[$record][$event_id][$row['field_name']] = $row['value']; $record_data[$record][$current_event_field] = $row['value']; } } } } } // Increment row counter $num_rows_returned++; } db_free_result($q); // If query returns 0 rows, then simply put default values for $record_data as placeholder for blanks and other defaults. // If DAGs were specified as input parameters but there are no records in those DAGs, then output NOTHING but a blank array. if ($num_rows_returned < 1 && !($hasDagRecords && !empty($groups))) { if ($recordsEmpty) { // Loop through ALL records and add default values for each foreach ($records as $this_record) { $record_data[$this_record] = $default_values; } } else { // Validate the records passed in $records and loop through them and add default values for each foreach (array_intersect($records, self::getRecordList($project_id)) as $this_record) { $record_data[$this_record] = $default_values; } } } /* print memory_get_usage()/1024/1024; //print_array($record_data); print_array($record_data_tmp_line); fseek($record_data_tmp_file, 0); echo stream_get_contents($record_data_tmp_file); */ // REPORTS ONLY: If the Record ID field is included in the report, then also display the Custom Record Label $extra_record_labels = array(); if ($returnFormat == 'html' && $recordIdInFields) { $extra_record_labels = Records::getCustomRecordLabelsSecondaryFieldAllRecords($records, false, 'all'); } // Sort by record and event name ONLY if we are NOT sorting by other fields if (empty($sortArray)) { ## SORT RECORDS BY RECORD NAME (i.e., array keys) using case insensitive natural sort natcaseksort($record_data); /* ## SORT EVENTS WITHIN EACH RECORD (LONGITUDINAL ONLY) if ($longitudinal) { // Create array of event_id's in order by arm_num, then by event order $event_order = array_keys($Proj->eventInfo); // Loop through each record and reorder the events (if has more than one event of data per record) foreach ($record_data as $this_record=>&$these_events) { // Set array to collect the data for this record in reordered form $this_record_data_reordered = array(); // Skip if there's only one event with data if (count($these_events) == 1) continue; // Loop through all existing PROJECT events in their proper order foreach (array_intersect($event_order, array_keys($these_events)) as $this_event_id) { // Add this event's data to reordered data array $this_record_data_reordered[$this_event_id] = $these_events[$this_event_id]; } // Replace old data with reordered data $record_data[$this_record] = $this_record_data_reordered; } // Remove unnecessary things for memory usage purposes unset($this_record_data_reordered, $these_events, $event_order); }*/ } ## ADD DATA ACCESS GROUP NAMES (IF APPLICABLE) if ($outputDags) { // If exporting labels, then create array of DAG labels if ($outputAsLabels) { $allDagLabels = $Proj->getGroups(); } // Get all DAG values for the records $sql = "select distinct record, value from redcap_data \n\t\t\t\t\twhere project_id = {$project_id} and field_name = '__GROUPID__'"; if (!$checkRecordNameEachLoop) { // For performance reasons, don't use "record in ()" unless we really need to $sql .= " and record in (" . prep_implode($records, false) . ")"; } $q = db_query($sql); while ($row = db_fetch_assoc($q)) { // Validate record name and DAG group_id value if (isset($allDags[$row['value']]) && isset($record_data[$row['record']])) { // Add unique DAG name to every event for this record // foreach (array_keys($record_data[$row['record']]) as $dag_event_id) { // Add DAG name or unique DAG name //$record_data[$row['record']][$dag_event_id]['redcap_data_access_group'] $record_data[$row['record']]['redcap_data_access_group'] = $outputAsLabels ? $allDagLabels[$row['value']] : $allDags[$row['value']]; // } } } unset($allDagLabels); } ## ADD DATES FROM SCHEDULE IF REQURIED if (isset($outputScheduleDates) && count($outputScheduleDates) > 0) { $sql = "select event_id, record, event_date, event_time, event_status " . "from redcap_events_calendar " . "where project_id = {$project_id} "; if (!$checkRecordNameEachLoop) { // For performance reasons, don't use "record in ()" unless we really need to $sql .= " and r.record in (" . prep_implode($records, false) . ")"; } $q = db_query($sql); while ($row = db_fetch_assoc($q)) { // Process further only if record is in our array if (!isset($record_data[$row['record']])) { continue; } if (array_search($row['event_id'], $outputScheduleDates) !== false) { $record_data[$row['record']]["[{$Proj->getUniqueEventNames($row['event_id'])}][___schedule_date]"] = trim("{$row['event_date']} {$row['event_time']}"); } } } ## ADD SURVEY IDENTIFIER AND TIMESTAMP FIELDS FOR ALL SURVEYS /* TODO Longitudinal Reports: include survey timestamps/urls/returncodes/survey queue links */ if ($outputSurveyFields || isset($outputSurveyUrls) && count($outputSurveyUrls) > 0) { $sql = "select r.record, r.first_submit_time, r.completion_time, p.participant_identifier, s.form_name, p.event_id, p.hash, r.return_code " . "from redcap_surveys s, redcap_surveys_response r, redcap_surveys_participants p, redcap_events_metadata a " . "where p.participant_id = r.participant_id and s.project_id = {$project_id} and s.survey_id = p.survey_id " . "and p.event_id = a.event_id "; //and r.first_submit_time is not null"; if (!$checkRecordNameEachLoop) { // For performance reasons, don't use "record in ()" unless we really need to $sql .= " and r.record in (" . prep_implode($records, false) . ")"; } $q = db_query($sql); while ($row = db_fetch_assoc($q)) { // Make sure we have this record-event in array first //if (!isset($record_data[$row['record']][$row['event_id']])) continue; if (!isset($record_data[$row['record']])) { continue; } /* // Add participant identifier if ($row['participant_identifier'] != "" && isset($default_values[$row['event_id']]['redcap_survey_identifier'])) { $record_data[$row['record']][$row['event_id']]['redcap_survey_identifier'] = html_entity_decode($row['participant_identifier'], ENT_QUOTES); } // If response exists but is not completed, note this in the export if ($dateShiftSurveyTimestamps && $row['completion_time'] != "") { // Shift the survey timestamp, if applicable $row['completion_time'] = Records::shift_date_format($row['completion_time'], $days_to_shift[$row['record']]); } elseif ($row['completion_time'] == "") { // Replace with text "[not completed]" if survey wasn't completed $row['completion_time'] = "[not completed]"; } // Add to record_data array if (isset($record_data[$row['record']][$row['event_id']][$row['form_name'].'_timestamp'])) { $record_data[$row['record']][$row['event_id']][$row['form_name'].'_timestamp'] = $row['completion_time']; }*/ $frm = $row['form_name']; $evt = $row['event_id']; if (array_search("{$evt}|{$frm}", $outputSurveyUrls) !== false) { // Found a record/survey we want to include $url = $row['completion_time'] == "" ? APP_PATH_WEBROOT_FULL . "surveys/?s=" . $row['hash'] : $row['completion_time']; $record_data[$row['record']]["[{$Proj->getUniqueEventNames($evt)}][{$frm}___url]"] = $url; } } } unset($days_to_shift); ## HASH THE RECORD ID (replace record names with hash value) if ($hashRecordID) { foreach ($record_data as $this_record => $eattr) { // Hash the record name using a system-level AND project-level salt $this_new_record = md5($salt . $this_record . $Proj->project['__SALT__']); // Add new record name $record_data[$this_new_record] = $record_data[$this_record]; // Remove the old one unset($record_data[$this_record]); // If Record ID field exists in the report, then set it too at the value level foreach ($eattr as $this_event_id => $attr) { if (isset($attr[$Proj->table_pk])) { //$record_data[$this_new_record][$this_event_id][$Proj->table_pk] = $this_new_record; $record_data[$this_new_record][$Proj->table_pk] = $this_new_record; } } } unset($eattr, $attr); } // Remove unnecessary things for memory usage purposes unset($records, $default_values, $fieldsKeys, $recordsKeys, $record_events_filtered); db_free_result($q); // // If we need to remove the record ID field, then loop through all events of data and remove it // If we need to remove the record ID field, then loop through all records of data and remove it if ($removeTablePk) { foreach ($record_data as $this_record => &$these_fields) { //&$these_events) { // foreach ($these_events as $this_event_id=>&$these_fields) { if (isset($these_fields[$Proj->table_pk])) { //unset($record_data[$this_record][$this_event_id][$Proj->table_pk]); unset($record_data[$this_record][$Proj->table_pk]); } // } } } ## RETURN DATA IN SPECIFIED FORMAT // ARRAY format if ($returnFormat == 'array') { // Return as-is (already in array format) return $record_data; } else { ## For non-array formats, reformat data array (e.g., add unique event names, separate check options) // HEADERS: Do initial loop through array to build headers (do JUST one loop) $headers = $checkbox_choice_labels = array(); /* foreach ($record_data as $this_record=>&$field_data) { // &$event_data) { // Loop through events in this record foreach ($event_data as $this_event_id=>&$field_data) { // Create array of all forms $all_forms = array_keys($Proj->forms); // Loop through fields in this event foreach ($field_data as $this_field=>$this_value) { // Skip the Record ID field since it will be redundant //if ($this_field == $table_pk) continue; // If field is only a sorting field and not a real data field to return, then skip it if ($applySortFields && in_array($this_field, $sortArrayRemoveFromData)) continue; $this_field = LongitudinalReports::getFieldFromEventField($this_field); // If a checkbox split into multiple fields if (is_array($this_value) && !$combine_checkbox_values) { // If exporting labels, get labels for this field if ($outputCsvHeadersAsLabels) { $this_field_enum = parseEnum($Proj->metadata[$this_field]['element_enum']); } // Loop through all checkbox choices and add as separate "fields" foreach ($this_value as $this_code=>$this_checked_value) { // Store original code before formatting $this_code_orig = $this_code; // If coded value is not numeric, then format to work correct in variable name (no spaces, caps, etc) $this_code = (Project::getExtendedCheckboxCodeFormatted($this_code)); // Add choice to header $headers[] = ($outputCsvHeadersAsLabels) ? str_replace($orig, $repl, strip_tags(label_decode($Proj->metadata[$this_field]['element_label'])))." (choice=".str_replace(array("'","\""),array("",""),$this_field_enum[$this_code_orig]).")" : $this_field."___".$this_code; } // If a normal field or DAG/Survey fields } else { // Get this field's form $this_form = $Proj->metadata[$this_field]['form_name']; // If the record ID field if ($this_field == $table_pk) { $headers[] = ($outputCsvHeadersAsLabels) ? str_replace($orig, $repl, strip_tags(label_decode($Proj->metadata[$table_pk]['element_label']))) : $table_pk; // If longitudinal, add unique event name to line if ($longitudinal) { $headers[] = ($outputCsvHeadersAsLabels) ? 'Event Name' : 'redcap_event_name'; } } // Check if a special field or a normal field elseif (!$outputCsvHeadersAsLabels) { // Add field to header array $headers[] = $this_field; // Add checkbox labels to array (only for $combine_checkbox_values=TRUE) if (is_array($this_value) && $combine_checkbox_values) { foreach (parseEnum($Proj->metadata[$this_field]['element_enum']) as $raw_coded_value=>$checkbox_label) { $checkbox_choice_labels[$raw_coded_value] = $checkbox_label; } } // Output labels for normal field or DAG/Survey fields } elseif ($this_field == 'redcap_data_access_group') { $headers[] = 'Data Access Group'; } elseif ($this_field == 'redcap_survey_identifier') { $headers[] = 'Survey Identifier'; } elseif (substr($this_field, -10) == '_timestamp' && in_array(substr($this_field, 0, -10), $all_forms)) { $headers[] = 'Survey Timestamp'; } else { $headers[] = str_replace($orig, $repl, strip_tags(label_decode($Proj->metadata[$this_field]['element_label']))); } } } unset($all_forms); // Stop after we have all the fields for the first event listed (that's all we need) break; // 2; // } } */ // Loop through fields in order specified in LongitudinalReport spec foreach ($fields as $this_eventfield) { // If field is only a sorting field and not a real data field to return, then skip it if ($applySortFields && in_array($this_eventfield, $sortArrayRemoveFromData)) { continue; } $this_eventref = LongitudinalReports::getEventFromEventField($this_eventfield); $this_field = LongitudinalReports::getFieldFromEventField($this_eventfield); // If a checkbox split into multiple fields // if (is_array($this_value) && !$combine_checkbox_values) { if ($Proj->isCheckbox($this_field) && !$combine_checkbox_values) { // If exporting labels, get labels for this field //if ($outputCsvHeadersAsLabels) { $this_field_enum = parseEnum($Proj->metadata[$this_field]['element_enum']); //} // Loop through all checkbox choices and add as separate "fields" foreach ($this_field_enum as $this_code => $this_checked_value) { // Store original code before formatting $this_code_orig = $this_code; // If coded value is not numeric, then format to work correct in variable name (no spaces, caps, etc) $this_code = Project::getExtendedCheckboxCodeFormatted($this_code); // Add choice to header // $headers[] = ($outputCsvHeadersAsLabels) // ? str_replace($orig, $repl, strip_tags(label_decode($Proj->metadata[$this_field]['element_label'])))." (choice=".str_replace(array("'","\""),array("",""),$this_field_enum[$this_code_orig]).")" // : $this_field."___".$this_code; if ($outputCsvHeadersAsLabels) { // Longitudinal Reports - also include event name in header labels/ref $event_id = $Proj->getEventIdUsingUniqueEventName($this_eventref); $event_name = REDCap::getEventNames(false, true, $event_id); $hdr_display = str_replace($orig, $repl, strip_tags(label_decode($Proj->metadata[$this_field]['element_label']))) . " ({$event_name})" . " (choice=" . str_replace(array("'", "\""), array("", ""), $this_field_enum[$this_code_orig]) . ")"; $headers[] = $hdr_display; } else { $headers[] = "[{$this_eventref}][{$this_field}___{$this_code}]"; } } // If a normal field or DAG/Survey fields } else { // Get this field's form $this_form = $Proj->metadata[$this_field]['form_name']; // If the record ID field if ($this_field == $table_pk) { $headers[] = $outputCsvHeadersAsLabels ? str_replace($orig, $repl, strip_tags(label_decode($Proj->metadata[$table_pk]['element_label']))) : $table_pk; // // If longitudinal, add unique event name to line // if ($longitudinal) { // $headers[] = ($outputCsvHeadersAsLabels) ? 'Event Name' : 'redcap_event_name'; // } } elseif (!$outputCsvHeadersAsLabels) { // Add field to header array $headers[] = $this_eventfield; // $this_field; // Add checkbox labels to array (only for $combine_checkbox_values=TRUE) //if (is_array($this_value) && $combine_checkbox_values) { if ($combine_checkbox_values && $Proj->isCheckbox($this_field)) { foreach (parseEnum($Proj->metadata[$this_field]['element_enum']) as $raw_coded_value => $checkbox_label) { $checkbox_choice_labels[$raw_coded_value] = $checkbox_label; } } /* // Output labels for normal field or DAG/Survey fields } elseif ($this_field == 'redcap_data_access_group') { $headers[] = 'Data Access Group'; } elseif ($this_field == 'redcap_survey_identifier') { $headers[] = 'Survey Identifier'; } elseif (substr($this_field, -10) == '_timestamp' && in_array(substr($this_field, 0, -10), $all_forms)) { $headers[] = 'Survey Timestamp'; */ } else { // $headers[] = str_replace($orig, $repl, strip_tags(label_decode($Proj->metadata[$this_field]['element_label']))); // Longitudinal Reports - also include event name in header labels/ref $event_id = $Proj->getEventIdUsingUniqueEventName($this_eventref); $event_name = REDCap::getEventNames(false, true, $event_id); $hdr_display = str_replace($orig, $repl, strip_tags(label_decode($Proj->metadata[$this_field]['element_label']))) . " ({$event_name})"; $headers[] = $hdr_display; } } } // Add other fields at the end (DAG, survey stuff...) if ($outputDags) { $headers[] = $outputCsvHeadersAsLabels ? 'Data Access Group' : 'redcap_data_access_group'; } if ($outputSurveyFields) { $headers[] = 'Survey Identifier'; $headers[] = 'Survey Timestamp'; } if (isset($outputScheduleDates) && count($outputScheduleDates) > 0) { foreach ($outputScheduleDates as $evt) { if ($outputCsvHeadersAsLabels) { $headers[] = "Schedule Date ({$Proj->eventInfo[$evt]['name_ext']})"; } else { $headers[] = "[{$Proj->getUniqueEventNames($evt)}][___schedule_date]"; } } } if (isset($outputSurveyUrls) && count($outputSurveyUrls) > 0) { foreach ($outputSurveyUrls as $evtSurv) { //Event id/survey form stored as pipe-separated pair e.g. 2365|my_survey $es = explode('|', $evtSurv); if ($outputCsvHeadersAsLabels) { $headers[] = label_decode(strip_tags($Proj->forms[$es[1]]['menu'])) . " URL ({$Proj->eventInfo[$evt]['name_ext']})"; } else { $headers[] = "[{$Proj->getUniqueEventNames($es[0])}][{$es['1']}___url]"; } } } // Place formatted data into $record_data_formatted $record_data_formatted = array(); // Set line/item number for each record/event //$recordEventNum = 0; $recordNum = 0; // If no results were returned (empty array with no values), then output row with message stating that if (!$filterReturnedEmptySet) { // Loop through array and output line as CSV foreach ($record_data as $this_record => &$field_data) { // &$event_data) { // Loop through events in this record // foreach ($event_data as $this_event_id=>&$field_data) { // // Loop through fields in this event // Loop through fields in order specified in setup foreach ($fields as $this_eventfield) { $this_eventref = LongitudinalReports::getEventFromEventField($this_eventfield); $this_field = LongitudinalReports::getFieldFromEventField($this_eventfield); $this_value = $field_data[$this_eventfield]; // Is value an array? (i.e. a checkbox) $value_is_array = is_array($this_value); // Check field type if ($value_is_array && !$combine_checkbox_values) { // Loop through all checkbox choices and add as separate "fields" foreach ($this_value as $this_code => $this_checked_value) { // If coded value is not numeric, then format to work correct in variable name (no spaces, caps, etc) $this_code = Project::getExtendedCheckboxCodeFormatted($this_code); //$record_data_formatted[$recordEventNum][$this_field."___".$this_code] = $this_checked_value; $record_data_formatted[$recordNum]["[{$this_eventref}][{$this_field}" . "___" . "{$this_code}]"] = $this_checked_value; } } elseif ($value_is_array && $combine_checkbox_values) { // Loop through all checkbox choices and create comma-delimited list of all *checked* options as value of single field $checked_off_options = array(); foreach ($this_value as $this_code => $this_checked_value) { // If value is 0 (unchecked), then skip it here. (Also skip if blank, which means that this form not designated for this event.) if ($this_checked_value == '0' || $this_checked_value == '' || $this_checked_value == 'Unchecked') { continue; } // If coded value is not numeric, then format to work correct in variable name (no spaces, caps, etc) // $this_code = (Project::getExtendedCheckboxCodeFormatted($this_code)); // Add checked off option code to array of checked off options $checked_off_options[] = $outputAsLabels ? $checkbox_choice_labels[$this_code] : $this_code; } // Add checkbox as single field //$record_data_formatted[$recordEventNum][$this_field] = implode(",", $checked_off_options); $record_data_formatted[$recordNum]["[{$this_eventref}][{$this_field}]"] = implode(",", $checked_off_options); } else { // Add record name to line if ($this_field == $table_pk) { //$record_data_formatted[$recordEventNum][$table_pk] = $this_record; $record_data_formatted[$recordNum][$table_pk] = $this_record; // // If longitudinal, add unique event name to line // if ($longitudinal) { // if ($outputAsLabels) { // $record_data_formatted[$recordEventNum]['redcap_event_name'] = $event_labels[$this_event_id]; // } else { // $record_data_formatted[$recordEventNum]['redcap_event_name'] = $unique_events[$this_event_id]; // } // } } else { // Add field and its value //$record_data_formatted[$recordEventNum][$this_field] = $this_value; $record_data_formatted[$recordNum]["[{$this_eventref}][{$this_field}]"] = $this_value; } } } // Add data for other fields at the end (DAG, survey stuff...) if ($outputDags) { $record_data_formatted[$recordNum]["redcap_data_access_group"] = $field_data["redcap_data_access_group"]; } if ($outputSurveyFields) { $record_data_formatted[$recordNum]["Survey Identifier"] = "_"; $record_data_formatted[$recordNum]["Survey Timestamp"] = "_"; } if (isset($outputScheduleDates) && count($outputScheduleDates) > 0) { foreach ($outputScheduleDates as $evt) { $colRef = "[{$Proj->getUniqueEventNames($evt)}][___schedule_date]"; $record_data_formatted[$recordNum][$colRef] = $field_data[$colRef]; } } if (isset($outputSurveyUrls) && count($outputSurveyUrls) > 0) { foreach ($outputSurveyUrls as $evtSurv) { //Event id/survey form stored as pipe-separated pair e.g. 2365|my_survey $es = explode('|', $evtSurv); $colRef = "[{$Proj->getUniqueEventNames($es[0])}][{$es['1']}___url]"; //$url = ($returnFormat == 'html') // ? "<a href=\"{$field_data[$colRef]}\" target=\"_blank\">{$field_data[$colRef]}</a>" // : $field_data[$colRef]; $record_data_formatted[$recordNum][$colRef] = $field_data[$colRef]; } } // Increment item counter //$recordEventNum++; $recordNum++; //} // Remove record from array to free up memory as we go unset($record_data[$this_record]); } } unset($record_data); // APPLY MULTI-FIELD SORTING if ($applySortFields) { // Move array keys to array with them as values $sortFields = array_keys($sortArray); $sortTypes = array_values($sortArray); // Determine if any of the sort fields are numerical fields (number, integer, calc, slider) $sortFieldIsNumber = array(); foreach ($sortFields as $this_sort_field) { $this_sort_field = LongitudinalReports::getFieldFromEventField($this_sort_field); $field_type = $Proj->metadata[$this_sort_field]['element_type']; $val_type = $Proj->metadata[$this_sort_field]['element_validation_type']; $sortFieldIsNumber[] = $this_sort_field == $Proj->table_pk && $Proj->project['auto_inc_set'] || $val_type == 'float' || $val_type == 'int' || $field_type == 'calc' || $field_type == 'slider'; } // Loop through each record/event and build separate array for each sort field $sortFieldValues = array(); foreach ($record_data_formatted as &$line) { foreach ($sortFields as $key => $this_sort_field) { // Add value to array as lower case (since we need to do case insensitive sorting) $sortFieldValues[$key][] = strtolower($line[$this_sort_field]); } } // print_array($sortFieldValues); // Sort the data array if (count($sortFieldValues) == 1) { // One sort field array_multisort($sortFieldValues[0], $sortTypes[0] == 'ASC' ? SORT_ASC : SORT_DESC, $sortFieldIsNumber[0] ? SORT_NUMERIC : SORT_STRING, $record_data_formatted); } elseif (count($sortFieldValues) == 2) { // Two sort fields array_multisort($sortFieldValues[0], $sortTypes[0] == 'ASC' ? SORT_ASC : SORT_DESC, $sortFieldIsNumber[0] ? SORT_NUMERIC : SORT_STRING, $sortFieldValues[1], $sortTypes[1] == 'ASC' ? SORT_ASC : SORT_DESC, $sortFieldIsNumber[1] ? SORT_NUMERIC : SORT_STRING, $record_data_formatted); } else { // Three sort fields array_multisort($sortFieldValues[0], $sortTypes[0] == 'ASC' ? SORT_ASC : SORT_DESC, $sortFieldIsNumber[0] ? SORT_NUMERIC : SORT_STRING, $sortFieldValues[1], $sortTypes[1] == 'ASC' ? SORT_ASC : SORT_DESC, $sortFieldIsNumber[1] ? SORT_NUMERIC : SORT_STRING, $sortFieldValues[2], $sortTypes[2] == 'ASC' ? SORT_ASC : SORT_DESC, $sortFieldIsNumber[2] ? SORT_NUMERIC : SORT_STRING, $record_data_formatted); } // If any sorting fields did NOT exist in $fields originally (but were added so their data could be obtained for // sorting purposes only), then remove them now. if (!empty($sortArrayRemoveFromData)) { foreach ($sortArrayRemoveFromData as $this_field) { foreach ($record_data_formatted as &$this_item) { // Remove field from this record-event unset($this_item[$this_field]); } } } // Remove vars to save memory unset($sortFieldValues); } ## HTML format (i.e., report) if ($returnFormat == 'html') { // Build array of events with unique event name as key and full event name as value $eventsUniqueFullName = $eventsUniqueEventId = array(); if ($longitudinal) { foreach ($unique_events as $this_event_id => $this_unique_name) { // Arrays event name and event_id with unique event name as key $eventsUniqueFullName[$this_unique_name] = str_replace($orig, $repl, strip_tags(label_decode($Proj->eventInfo[$this_event_id]['name_ext']))); $eventsUniqueEventId[$this_unique_name] = $this_event_id; } } // Build array of DAGs with unique DAG names as key and $dagUniqueFullName = array(); foreach ($Proj->getUniqueGroupNames() as $this_group_id => $this_unique_dag) { $dagUniqueFullName[$this_unique_dag] = str_replace($orig, $repl, strip_tags(label_decode($Proj->getGroups($this_group_id)))); } // Set number of results $num_results_returned = count($record_data_formatted); // If we're JUST returning Records/Events array and NOT the html report, then collect all records/event_ids and return if ($returnIncludeRecordEventArray) { // Collect records/event_ids in array $includeRecordsEvents = array(); foreach ($record_data_formatted as $key => $item) { // Add record/event $this_event_id = $longitudinal ? $eventsUniqueEventId[$item['redcap_event_name']] : $Proj->firstEventId; $includeRecordsEvents[$item[$Proj->table_pk]][$this_event_id] = true; // Remove each as we go to save memory unset($record_data_formatted[$key]); } // Return array of the whole table, number of results returned, and total number of items queried return array($includeRecordsEvents, $num_results_returned); } // PAGING FOR REPORTS: If has more than $num_per_page results, then page it $num_per_page per page // (only do this for pre-defined reports though) $num_per_page = LR_RESULTS_PER_PAGE; $limit_begin = 0; if (isset($_GET['pagenum']) && is_numeric($_GET['pagenum'])) { $limit_begin = ($_GET['pagenum'] - 1) * $num_per_page; } elseif (!isset($_GET['pagenum'])) { $_GET['pagenum'] = 1; } else { $_GET['pagenum'] = 'ALL'; } $pageNumDropdown = ""; //if (isset($_POST['report_id']) && !is_numeric($_POST['report_id']) && $num_results_returned > $num_per_page) if ($num_results_returned > $num_per_page) { // Build drop-down list of page numbers $num_pages = ceil($num_results_returned / $num_per_page); // Only display drop-down if we have more than one page if ($num_pages > 1) { // Initialize array of options for drop-down $pageNumDropdownOptions = array('ALL' => '-- ' . $lang['docs_44'] . ' --'); // Loop through pages for ($i = 1; $i <= $num_pages; $i++) { $end_num = $i * $num_per_page; $begin_num = $end_num - $num_per_page + 1; $value_num = $end_num - $num_per_page; if ($end_num > $num_results_returned) { $end_num = $num_results_returned; } // If Record ID field not included in report, then use "results 1 through 100" instead of "A101 through B203" using record names if (isset($record_data_formatted[0][$Proj->table_pk])) { $resultNamePrefix = $lang['data_entry_177'] . " "; $resultName1 = "\"" . $record_data_formatted[$begin_num - 1][$Proj->table_pk] . "\""; $resultName2 = "\"" . $record_data_formatted[$end_num - 1][$Proj->table_pk] . "\""; } else { $resultNamePrefix = $lang['report_builder_112'] . " "; $resultName1 = $begin_num; $resultName2 = $end_num; } $pageNumDropdownOptions[$i] = "{$resultName1} {$lang['data_entry_216']} {$resultName2}"; } // Create HTML for pagenum drop-down $pageNumDropdown = RCView::div(array('class' => 'chklist hide_in_print report_pagenum_div'), (!(isset($_GET['pagenum']) && is_numeric($_GET['pagenum'])) ? '' : RCView::span(array('style' => 'font-weight:bold;margin-right:7px;font-size:13px;'), "{$lang['survey_132']} {$_GET['pagenum']} {$lang['survey_133']} {$num_pages}{$lang['colon']}")) . $resultNamePrefix . RCView::select(array('class' => 'x-form-text x-form-field', 'style' => 'font-size:11px;margin-left:6px;margin-right:4px;padding-right:0;padding-top:1px;height:19px;', 'onchange' => "loadReportNewPage(this.value);"), $pageNumDropdownOptions, $_GET['pagenum'], 500) . $lang['survey_133'] . RCView::span(array('style' => 'font-weight:bold;margin:0 4px;font-size:13px;'), User::number_format_user($num_results_returned)) . $lang['report_builder_113']); unset($pageNumDropdownOptions); } // Filter the results down to just a single page if (is_numeric($_GET['pagenum'])) { $record_data_formatted = array_slice($record_data_formatted, $limit_begin, $num_per_page, true); } } // Set extra set of reserved field names for survey timestamps and return codes pseudo-fields $reserved_field_names2 = explode(',', implode("_timestamp,", array_keys($Proj->forms)) . "_timestamp" . "," . implode("_return_code,", array_keys($Proj->forms)) . "_return_code"); $reserved_field_names2 = $reserved_field_names + array_fill_keys($reserved_field_names2, 'Survey Timestamp'); // Place all html in $html $html = $pageNumDropdown . "<table id='report_table' class='dt2' style='margin:0;font-family:Verdana;font-size:11px;'>"; $mc_choices = array(); // Array to store fields to which user has no form-level access $fields_no_access = array(); // Add form fields where user has no access foreach ($user_rights['forms'] as $this_form => $this_access) { if ($this_access == '0') { $fields_no_access[$this_form . "_timestamp"] = true; } } // Loop through header fields and build HTML row $datetime_convert = array(); $row = ""; foreach ($headers as $this_hdr_ef) { $this_hdr_ev = LongitudinalReports::getEventFromEventField($this_hdr_ef); $this_hdr = LongitudinalReports::getFieldFromEventField($this_hdr_ef); // Set original field name $this_hdr_orig = $this_hdr; // Determine if a checkbox $isCheckbox = false; $checkbox_label_append = ""; if (!isset($Proj->metadata[$this_hdr]) && strpos($this_hdr, "___") !== false) { // Set $this_hdr as the true field name list($this_hdr, $raw_coded_value_formatted) = explode("___", $this_hdr, 2); $isCheckbox = $Proj->isCheckbox($this_hdr); // Obtain the label for this checkbox choice foreach (parseEnum($Proj->metadata[$this_hdr]['element_enum']) as $raw_coded_value => $checkbox_label) { if ($this_hdr_orig == Project::getExtendedCheckboxFieldname($this_hdr, $raw_coded_value)) { $checkbox_label_append = " (Choice = '" . strip_tags(label_decode($checkbox_label)) . "')"; // If user does not have form-level access to this field's form if ($user_rights['forms'][$Proj->metadata[$this_hdr]['form_name']] == '0') { $fields_no_access[$this_hdr_orig] = true; } break; } } } // If user does not have form-level access to this field's form if (isset($Proj->metadata[$this_hdr]) && $this_hdr != $Proj->table_pk && $user_rights['forms'][$Proj->metadata[$this_hdr]['form_name']] == '0') { $fields_no_access[$this_hdr] = true; } // If field is a reserved field name (redcap_event_name, redcap_data_access_group) if (!isset($Proj->metadata[$this_hdr_orig]) && !$isCheckbox) { if (isset($reserved_field_names2[$this_hdr_orig])) { $field_type = ''; $field_label_display = strip_tags(label_decode($reserved_field_names2[$this_hdr_orig])); } else { if ($this_hdr_orig == "___schedule_date") { $field_label_display = "Schedule Date"; } else { if (strpos($this_hdr_orig, "___url") !== false) { $frm = str_replace("___url", "", $this_hdr_orig); $field_label_display = "{$Proj->forms[$frm]['menu']} URL"; } } } } else { $field_type = $Proj->metadata[$this_hdr]['element_type']; $field_label = strip_tags(label_decode($Proj->metadata[$this_hdr]['element_label'])); if (strlen($field_label) > 100) { $field_label = substr($field_label, 0, 67) . " ... " . substr($field_label, -30); } $field_label_display = $field_label . $checkbox_label_append; } // Longitudinal Reports - also include event name in header labels/ref (unless lone pk field) if ($this_hdr_ev !== '') { $event_id = $Proj->getEventIdUsingUniqueEventName($this_hdr_ev); $event_name = REDCap::getEventNames(false, true, $event_id); $field_label_display .= "<div style='font-weight:normal;color:#800000;margin:3px 0;'>{$event_name}</div>"; } // Add field to header html row $row .= "<th" . (isset($fields_no_access[$this_hdr]) ? " class=\"form_noaccess\"" : '') . ">" . "{$field_label_display}<div class=\"rprthdr\">" . str_replace('][', ']<br>[', implode("_<wbr>", explode("_", $this_hdr_ef))) . "</div></th>"; // Place only MC fields into array to reference if (in_array($field_type, array('yesno', 'truefalse', 'sql', 'select', 'radio', 'advcheckbox', 'checkbox'))) { // Convert sql field types' query result to an enum format $enum = $field_type == "sql" ? getSqlFieldEnum($Proj->metadata[$this_hdr]['element_enum']) : $Proj->metadata[$this_hdr]['element_enum']; // Add to array if ($isCheckbox) { // Reformat checkboxes to export format field name foreach (parseEnum($enum) as $raw_coded_value => $checkbox_label) { $this_hdr_chkbx = $Proj->getExtendedCheckboxFieldname($this_hdr, $raw_coded_value); $mc_choices[$this_hdr_chkbx] = array('0' => "Unchecked", '1' => "Checked"); } } else { $mc_choices[$this_hdr] = parseEnum($enum); } } // Put all date/time fields into array for quick converting of their value to desired date format if (!$isCheckbox) { $val_type = $Proj->metadata[$this_hdr]['element_validation_type']; if (substr($val_type, 0, 4) == 'date' && (substr($val_type, -4) == '_mdy' || substr($val_type, -4) == '_dmy')) { // Add field name as key to array with 'mdy' or 'dmy' as value $datetime_convert[$this_hdr] = substr($val_type, -3); } if ($this_hdr_orig == '___schedule_date') { // Include event schedule dates for date formatting as per user pref $formatPref = 'ymd'; if (substr($datetime_format, 0, 1) == "D") { $formatPref = 'dmy'; } else { if (substr($datetime_format, 0, 1) == "M") { $formatPref = 'mdy'; } } $datetime_convert[$this_hdr_orig] = 'dmy'; } } } $html .= "<thead><tr class=\"hdr2\">{$row}</tr></thead>"; // If no data, then output row with message noting this if (empty($record_data_formatted)) { $html .= RCView::tr(array('class' => 'odd'), RCView::td(array('style' => 'color:#777;', 'colspan' => count($headers)), $lang['report_builder_87'])); } // If record ID is in report for a classic project and will thus be displayed as a link, then get // the user's first form based on their user rights (so we don't point to a form that they don't have access to.) if ($recordIdInFields && !$longitudinal) { foreach (array_keys($Proj->forms) as $this_form) { if ($user_rights['forms'][$this_form] == '0') { continue; } $first_form = $this_form; break; } } // DATA: Loop through each row of data (record-event) and output to html $j = 1; foreach ($record_data_formatted as $key => &$line) { // Set row class $class = $j % 2 == 1 ? "odd" : "even"; $row = ""; // Loop through each element in row foreach ($line as $this_eventfieldname => $this_value) { $this_eventname = LongitudinalReports::getEventFromEventField($this_eventfieldname); $this_fieldname = LongitudinalReports::getFieldFromEventField($this_eventfieldname); // Check for form-level user access to this field if (isset($fields_no_access[$this_fieldname])) { // User has no rights to this field $row .= "<td class=\"form_noaccess\">-</td>"; } else { // If redcap_event_name field if ($this_fieldname == 'redcap_event_name') { $cell = $eventsUniqueFullName[$this_value]; } elseif ($this_fieldname == 'redcap_data_access_group') { $cell = $dagUniqueFullName[$this_value]; } elseif (strpos($this_fieldname, "___url") !== false) { if (filter_var($this_value, FILTER_VALIDATE_URL)) { $hash = substr($this_value, -10); if (strpos($hash, '=') !== false) { $hash = substr($this_value, -6); } $cell = RCView::a(array('href' => $this_value, 'target' => '_blank', 'style' => 'margin-right:10px;'), RCView::img(array('src' => 'link.png', 'style' => 'vertical-align:middle;'))) . RCView::a(array('href' => 'javascript:;', 'onclick' => "getAccessCode('{$hash}');"), !gd2_enabled() ? RCView::img(array('src' => 'ticket_arrow.png', 'style' => 'vertical-align:middle;')) : RCView::img(array('src' => 'access_qr_code.gif', 'style' => 'vertical-align:middle;'))); } else { // Show completion timestamp $cell = DateTimeRC::datetimeConvert(substr($this_value, 0, 16), 'ymd', DateTimeRC::get_user_format_base()); } } elseif (isset($mc_choices[$this_fieldname])) { // Get option label $cell = $mc_choices[$this_fieldname][$this_value]; // PIPING (if applicable) if ($do_label_piping && in_array($this_fieldname, $piping_receiver_fields)) { $cell = strip_tags(Piping::replaceVariablesInLabel($cell, $line[$Proj->table_pk], $longitudinal ? $Proj->getEventIdUsingUniqueEventName($line['redcap_event_name']) : $Proj->firstEventId, $piping_record_data)); } // Append raw coded value if (trim($this_value) != "") { $cell .= " <span class=\"ch\">({$this_value})</span>"; } } elseif (substr($this_fieldname, -10) == '_timestamp' && isset($reserved_field_names2[$this_fieldname])) { // Convert datetime to user's preferred date format if ($this_value == "[not completed]") { $cell = $this_value; } else { $cell = DateTimeRC::datetimeConvert(substr($this_value, 0, 16), 'ymd', DateTimeRC::get_user_format_base()); } } else { // If a date/time field, then convert value to its designated date format (YMD, MDY, DMY) if (isset($datetime_convert[$this_fieldname])) { $cell = DateTimeRC::datetimeConvert($this_value, 'ymd', $datetime_convert[$this_fieldname]); } else { $cell = nl2br(htmlspecialchars($this_value, ENT_QUOTES)); } } // If record name, then convert it to a link (unless project is archived/inactive) if ($Proj->project['status'] < 2 && $this_fieldname == $Proj->table_pk) { // Link URL $this_arm = $Proj->longitudinal ? $Proj->eventInfo[$eventsUniqueEventId[$line['redcap_event_name']]]['arm_num'] : $Proj->firstArmNum; if ($longitudinal) { $this_url = "grid.php?pid={$Proj->project_id}&id=" . removeDDEending($this_value) . "&arm={$this_arm}"; } else { $this_url = "index.php?pid={$Proj->project_id}&id=" . removeDDEending($this_value) . "&page=" . $first_form; } // If has custom record label, then display it $this_custom_record_label = isset($extra_record_labels[$this_arm][$this_value]) ? " " . $extra_record_labels[$this_arm][$this_value] : ''; // Wrap record name with link HTML $cell = RCView::a(array('href' => APP_PATH_WEBROOT . "DataEntry/{$this_url}", 'class' => 'rl'), removeDDEending($cell)) . $this_custom_record_label; } // Add cell to row $row .= "<td>{$cell}</td>"; } } // Add row $html .= "<tr class=\"{$class}\">{$row}</tr>"; // Remove line from array to free up memory as we go unset($record_data_formatted[$key]); $j++; } unset($row); // Build entire HTML table $html .= "</table>" . $pageNumDropdown; // Return array of the whole table, number of results returned, and total number of items queried return array($html, $num_results_returned); } elseif ($returnFormat == 'csv') { // Open connection to create file in memory and write to it $fp = fopen('php://memory', "x+"); // Add header row to CSV fputcsv($fp, $headers); // Loop through array and output line as CSV foreach ($record_data_formatted as $key => &$line) { // Write this line to CSV file fputcsv($fp, $line); // Remove line from array to free up memory as we go unset($record_data_formatted[$key]); } // Open file for reading and output to user fseek($fp, 0); $csv_file_contents = stream_get_contents($fp); fclose($fp); // Return CSV string return $csv_file_contents; } elseif ($returnFormat == 'xml') { // Convert all data into XML string $xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<records>\n"; // Loop through array and add to XML string foreach ($record_data_formatted as $key => &$item) { // Begin item $xml .= "<item>"; // Loop through all fields/values foreach ($item as $this_field => $this_value) { // If ]]> is found inside this value, then "escape" it (cannot really escape it but can do clever replace with "]]]]><![CDATA[>") if (strpos($this_value, "]]>") !== false) { $this_value = str_replace("]]>", "]]]]><![CDATA[>", $this_value); } // Add value $xml .= "<{$this_field}><![CDATA[{$this_value}]]></{$this_field}>"; } // End item $xml .= "</item>\n"; // Remove line from array to free up memory as we go unset($record_data_formatted[$key]); } // End XML string $xml .= "</records>"; // Return XML string return $xml; } elseif ($returnFormat == 'json') { // Convert all data into JSON string (do record by record to preserve memory better) $json = ''; foreach ($record_data_formatted as $key => &$item) { // Loop through each record and encode $json .= "," . json_encode($item); // Remove line from array to free up memory as we go unset($record_data_formatted[$key]); } return '[' . substr($json, 1) . ']'; } } }
$reportData['orderby_field2'] = $orderby_field2; $reportData['orderby_sort2'] = $orderby_sort2; $reportData['orderby_field3'] = $orderby_field3; $reportData['orderby_sort3'] = $orderby_sort3; $reportData['update_by'] = $userid; $reportData['update_at'] = $now->format('Y-m-d H:i:s'); $reportData['report_complete'] = '2'; $success = true; $data = array(); $data[] = $reportData; // Can handle multiple records - not needed here $success = LongitudinalReports::save($data); // If there are errors, then roll back all changes if (!$success) { //$errors > 0) { // Errors occurred, so undo any changes made // db_query("ROLLBACK"); // Return '0' for error exit('0'); } else { // Logging $log_descrip = $_GET['report_id'] != 0 ? "Edit longitudinal report" : "Create longitudinal report"; REDCap::logEvent($log_descrip, "report_id = {$report_id}: " . print_r($reportData, true)); // Commit changes // db_query("COMMIT"); // Response $dialog_title = RCView::img(array('src' => 'tick.png', 'style' => 'vertical-align:middle')) . RCView::span(array('style' => 'color:green;vertical-align:middle'), $lang['report_builder_01']); $dialog_content = RCView::div(array('style' => 'font-size:14px;'), $lang['report_builder_73'] . " \"" . RCView::span(array('style' => 'font-weight:bold;'), RCView::escape($title)) . "\" " . $lang['report_builder_74']); // Output JSON response print json_encode(array('report_id' => $report_id, 'newreport' => $_GET['report_id'] == 0 ? 1 : 0, 'title' => $dialog_title, 'content' => $dialog_content)); }
$item = $event['cm_oth_cmindc']; } $desc_array[] = get_field_label($field, $project_id) . ': <strong>' . $item . "</strong>"; } } $event_start = $event['cm_cmstdtc'] != '' ? $event['cm_cmstdtc'] : $rfstdtc; if ($event['cm_cmtrt'] != '') { $eventAtts[] = get_event_array($event_start, '', '', implode("<br />", $desc_array), $event['cm_cmtrt'], '', '', $url); } } } /** * transfusions */ $fields = array('xfsn_cmstdtc', 'xfsn_cmtrt', 'xfsn_cmdose', 'xfsn_cmindc'); $transfusion_data = REDCap::getData('array', $subjid, $fields); foreach ($transfusion_data AS $subject) { foreach ($subject AS $event_id => $event) { $desc_array = array(); $url = APP_PATH_WEBROOT_FULL . "redcap_v" . $redcap_version . "/DataEntry/index.php?pid=$project_id&page=transfusions&id=$subjid&event_id=$event_id"; foreach ($event AS $field => $item) { if ($item != '' && !in_array($field, array('xfsn_cmstdtc', 'xfsn_cmtrt'))) { $desc_array[] = get_field_label($field, $project_id) . ': <strong>' . $item . "</strong>"; } } $eventAtts[] = get_event_array($event['xfsn_cmstdtc'], '', '', implode("<br />", $desc_array), $event['xfsn_cmtrt'], 'red', '', $url); } } /** * generate and return JSON to timeline script. */
/** * @param $record * @param $event_id * @param $group_id * @param $debug */ function schedule_surveys($record, $event_id, $group_id, $debug) { global $Proj, $project_id, $user_rights, $table_pk; /** * if the user is in a DAG */ if ($user_rights['group_id'] != "") { /** * does this record exist? */ $q = db_query("SELECT 1 from redcap_data WHERE project_id = $project_id AND record = '$record' LIMIT 1"); if (db_num_rows($q) > 0) { /** * is the record in this users DAG? */ $q = db_query("SELECT 1 from redcap_data WHERE project_id = $project_id AND record = '$record' AND field_name = '__GROUPID__' AND value = '{$user_rights['group_id']}' LIMIT 1"); if (db_num_rows($q) < 1) { /** * record is not in Users DAG! */ REDCap::logEvent('Scheduled record is not in users DAG', '', '', $record, $event_id, $project_id); exit; } } } /** * check to see if the subject has an existing schedule on an existing arm */ $sub = "SELECT DISTINCT e.arm_id from redcap_events_calendar c, redcap_events_metadata e WHERE c.project_id = $project_id AND c.record = '$record' AND c.event_id = e.event_id"; $sched_arm_result = db_query("SELECT arm_num FROM redcap_events_arms WHERE project_id = $project_id AND arm_id IN (" . pre_query($sub) . ")"); if ($sched_arm_result) { $trt = Treatment::getTrtInfo($record); if ($debug) { error_log(print_r($trt, true)); } $tx_start_date = $trt['rfxstdtc']; $rand_date = $trt['rand_date']; $dates = array(); $arm_num = db_result($sched_arm_result, 0, 'arm_num'); if (isset($arm_num) && $arm_num != '') { // subject has an existing schedule. keep existing event_id > arm structure if ($arm_num != '1') { // make sure we don't put anything in the first arm $q = db_query("SELECT * from redcap_events_metadata m, redcap_events_arms a WHERE a.project_id = $project_id AND a.arm_id = m.arm_id AND a.arm_num = $arm_num order by m.day_offset, m.descrip"); if ($q) { while ($row = db_fetch_assoc($q)) { // if we have no $arm_num, this will be empty /** * get the event date ($rand_date for baseline and $tx_start_date + day_offset) */ $row['day_offset'] = $arm_num != $trt['timing_arm_num'] ? $trt['timing_offsets'][$row['descrip']] : $row['day_offset']; if (in_array($row['descrip'], array('Baseline', 'EOT+1Year', 'EOT+3Year'))) { $this_event_date = isset($rand_date) && $rand_date != '' ? add_date($rand_date, $row['day_offset']) : null; } else { $this_event_date = isset($tx_start_date) && $tx_start_date != '' ? add_date($tx_start_date, $row['day_offset']) : null; } $dates[$row['event_id']] = $this_event_date; } db_free_result($q); } } else { REDCap::logEvent('Scheduling attempted in invalid arm', '', '', $record, $event_id, $project_id); } } else { // subject's schedule is new. put dates into event_ids for this arm $arm_result = db_query("SELECT arm_num FROM redcap_events_arms WHERE project_id = '$project_id' AND arm_name = '{$trt['arm']}'"); if ($arm_result) { $arm_num = db_result($arm_result, 0, 'arm_num'); if ($arm_num != '1') { $q = db_query("SELECT * from redcap_events_metadata m, redcap_events_arms a WHERE a.project_id = $project_id AND a.arm_id = m.arm_id AND a.arm_num = $arm_num order by m.day_offset, m.descrip"); if ($q) { while ($row = db_fetch_assoc($q)) { // if we have no $arm_num, this will be empty /** * get the event date ($rand_date for baseline and $tx_start_date + day_offset) */ if (in_array($row['descrip'], array('Baseline', 'EOT+1Year', 'EOT+3Year'))) { $this_event_date = isset($rand_date) && $rand_date != '' ? add_date($rand_date, $row['day_offset']) : null; } else { $this_event_date = isset($tx_start_date) && $tx_start_date != '' ? add_date($tx_start_date, $row['day_offset']) : null; } $dates[$row['event_id']] = $this_event_date; } db_free_result($q); } } else { REDCap::logEvent('Scheduling attempted in invalid arm', '', '', $record, $event_id, $project_id); } db_free_result($arm_result); } } if ($debug) { error_log(print_r($dates, true)); } if (!empty($dates)) { /** * do we have an existing schedule? */ $sql = "SELECT c.event_date, c.baseline_date, e.* FROM redcap_events_calendar c, redcap_events_metadata e WHERE c.project_id = $project_id AND c.record = '$record' AND c.event_id = e.event_id AND e.arm_id IN (" . pre_query($sub) . ")"; $sched_result = db_query($sql); if ($sched_result) { $sql_all = array(); $sql_errors = array(); if (db_num_rows($sched_result) > 0) { while ($sched_row = db_fetch_assoc($sched_result)) { $base_date = in_array($sched_row['descrip'], array('Baseline', 'EOT+1Year', 'EOT+3Year')) ? $trt['rand_date'] : $trt['rfxstdtc']; /** * if the scheduled date is in the $dates array, we don't care about it, so ignore it and remove from $dates * if we have an existing schedule and the dates have changed, update the schedule and remove from $dates * if the base date has changed, update it and the schedule * whatever is left will be new dates, insert into schedule */ if ($dates[$sched_row['event_id']] == $sched_row['event_date']) { unset($dates[$sched_row['event_id']]); } if (isset($dates[$sched_row['event_id']]) && $dates[$sched_row['event_id']] != '' && $sched_row['event_date'] != $dates[$sched_row['event_id']]) { // the date has changed. update the date. $sql = "UPDATE redcap_events_calendar SET event_date = '{$dates[$sched_row['event_id']]}' WHERE record = '$record' AND project_id = '$project_id' AND group_id = '$group_id' AND event_id = '{$sched_row['event_id']}' AND event_date = '{$sched_row['event_date']}'"; if (!$debug) { if (db_query($sql)) { $sql_all[] = $sql; log_event($sql, "redcap_events_calendar", "MANAGE", $record, $sched_row['event_id'], "Update calendar event"); } else { $sql_errors[] = $sql; } } else { error_log($sql); } unset($dates[$sched_row['event_id']]); } if ($base_date != $sched_row['baseline_date']) { // the base_date has changed. this will only occur if the treatment start date or randomization date are changed in the study. $sql = "UPDATE redcap_events_calendar SET baseline_date = '" . prep($base_date) . "' WHERE record = '$record' AND project_id = '$project_id' AND group_id = '$group_id' AND event_id = '{$sched_row['event_id']}' AND baseline_date = '{$sched_row['baseline_date']}'"; if (!$debug) { if (db_query($sql)) { $sql_all[] = $sql; log_event($sql, "redcap_events_calendar", "MANAGE", $record, $sched_row['event_id'], "Update calendar event"); } else { $sql_errors[] = $sql; } } else { error_log($sql); } unset($dates[$sched_row['event_id']]); } } foreach ($dates AS $date_event_id => $date) { //Loop through dates and add them to the schedule $base_date = in_array($Proj->eventInfo[$date_event_id]['name'], array('Baseline', 'EOT+1Year', 'EOT+3Year')) ? $trt['rand_date'] : $trt['rfxstdtc']; if (isset($date) && $date != "") { //Add to table $sql = "INSERT INTO redcap_events_calendar (record, project_id, group_id, event_id, event_date, event_time, event_status, baseline_date) VALUES ('$record', $project_id, " . checkNull($group_id) . ", '" . prep($date_event_id) . "', '" . prep($date) . "', '" . null . "', 0, '$base_date')"; if (!$debug) { if (db_query($sql)) { $sql_all[] = $sql; } else { $sql_errors[] = $sql; } } else { error_log($sql); } } else { REDCap::logEvent('Schedule start date is not a valid date', '', '', $record, $event_id, $project_id); } } log_event(implode(";\n", $sql_all), "redcap_events_calendar", "MANAGE", $_GET['idnumber'], "$table_pk = '$record'", "Perform scheduling"); } else { foreach ($dates AS $date_event_id => $date) { //Loop through dates and add them to the schedule $base_date = in_array($Proj->eventInfo[$date_event_id]['name'], array('Baseline', 'EOT+1Year', 'EOT+3Year')) ? $trt['rand_date'] : $trt['rfxstdtc']; if (isset($date) && $date != "") { //Add to table $sql = "INSERT INTO redcap_events_calendar (record, project_id, group_id, event_id, event_date, event_time, event_status, baseline_date) VALUES ('$record', $project_id, " . checkNull($group_id) . ", '" . prep($date_event_id) . "', '" . prep($date) . "', '" . null . "', 0, '$base_date')"; if (!$debug) { if (db_query($sql)) { $sql_all[] = $sql; } else { $sql_errors[] = $sql; } } else { error_log($sql); } } else { REDCap::logEvent('Schedule start date is not a valid date', '', '', $record, $event_id, $project_id); } } log_event(implode(";\n", $sql_all), "redcap_events_calendar", "MANAGE", $_GET['idnumber'], "$table_pk = '$record'", "Perform scheduling"); } } db_free_result($sched_result); } db_free_result($sched_arm_result); } }
$timer['end_fields_' . $fragment] = microtime(true); } d($lab_fields); d($control_fields); /** * find baselines for each lab test */ $timer['start_data'] = microtime(true); $data = REDCap::getData('array', $subjects, $lab_fields); $timer['end_data'] = microtime(true); foreach ($data AS $subject_id => $subject) { d($subject_id); /** * get rfstdtc for this subject */ $tx_start_data = REDCap::getData('array', $subject_id, array("dm_rfstdtc")); $rfstdtc = $tx_start_data[$subject_id][$initial_event]['dm_rfstdtc']; /** * if treatment has started */ if (isset($rfstdtc) || $rfstdtc != '') { d($rfstdtc); /** * iterate the lab events for this subject */ foreach ($control_fields as $form_prefix => $labs) { foreach ($labs as $lab_prefix => $fields) { $lab_subject = array(); $reset = array(); foreach ($fields AS $field) { foreach ($subject AS $lab_event_id => $lab_event) {
*/ $timer['start_fields'] = microtime(true); $su_fields_result = db_query($fields_query); $su_fields = array('dm_usubjid'); if ($su_fields_result) { while ($su_fields_row = db_fetch_assoc($su_fields_result)) { foreach ($su_fields_row AS $field_key => $field_name) { if (!in_array($field_key, array('type', 'label'))) { $su_fields[] = $field_name; } } } db_free_result($su_fields_result); } $su_fields = array_unique($su_fields); $data = REDCap::getData('array', $subjects, $su_fields); $timer['have_data'] = microtime(true); $fields_result = db_query($fields_query); $timer['have_fields'] = microtime(true); if ($fields_result) { while ($fields = db_fetch_assoc($fields_result)) { foreach ($data AS $subject_id => $subject) { $usubjid = ''; foreach ($subject AS $event_id => $event) { $inner_vals = array(); if ($usubjid == '') { $usubjid = $event['dm_usubjid']; } if ($fields['type'] == 'descriptive') {
/** * AND today is TX stop date + 14 weeks ago, and no final outcome, data is due */ if (date("Y-m-d") >= (add_date($stop_date, 98, 0, 0)) && !in_array($outcome, array('SVR', 'VIRAL BREAKTHROUGH', 'RELAPSE', 'NON-RESPONDER'))) { $hcv_data_due = true; } } /** * if not followup eligible (and no TX stop - implied by ineligible)... */ if ((!$hcv_fu_eligible || !$post_tx_followup_eligible) && $started_tx && !$stopped_tx) { /** * is regimen SOF + RBV? */ $due_fields = array('sof_cmstdtc', 'rib_cmstdtc'); $due_data = REDCap::getData('array', $subject_id, $due_fields); $sof_rbv_regimen = false; $sof = array(); $rbv = array(); foreach ($due_data[$subject_id] AS $event_id => $event) { if ($event['sof_cmstdtc'] != '') { $sof[] = true; } if ($event['rib_cmstdtc'] != '') { $rbv[] = true; } } $sof_rbv_regimen = eval("return ((" . implode(' || ', $sof) . ") && (" . implode(' || ', $rbv) . "));"); /** * get genotype */
*/ global $Proj; $first_event_id = $Proj->firstEventId; $plugin_title = "Derive stuff"; /** * plugin title */ echo "<h3>$plugin_title</h3>"; /** * MAIN */ if ($debug) { $timer['main_start'] = microtime(true); } $fields = array('dm_usubjid'); $data = REDCap::getData('array', $subjects, $fields, $first_event_id); d($data); foreach ($data AS $subject_id => $subject) { /** * SUBJECT-LEVEL vars */ $var = array(); /** * MAIN EVENT LOOP */ foreach ($subject AS $event_id => $event) { foreach ($event AS $key => $value) { /** * do stuff */
/** * forms with locked records */ $table_csv = ""; $final_row = array(); $locked_forms_total = 0; $data_fields_total = 0; $data_queries_total = 0; $complete_forms_total = 0; $locked_forms = db_query("SELECT DISTINCT form_name FROM redcap_locking_data WHERE project_id = '$project_id' ORDER BY form_name ASC"); if ($locked_forms) { while ($locked_forms_array = db_fetch_assoc($locked_forms)) { $data_row = array(); $locked_event_ids_array = array(); $locked_records_array = array(); $fields = REDCap::getFieldNames($locked_forms_array['form_name']); $form_complete_field = $locked_forms_array['form_name'] . '_complete'; unset($fields[array_search($form_complete_field, $fields)]); $fields_string = "'" . implode("', '", $fields) . "'"; /** * pretty form names */ $pretty_form_names = array(); $pretty_form_name_result = db_query("SELECT form_menu_description FROM redcap_metadata WHERE project_id = '$project_id' AND form_name = '{$locked_forms_array['form_name']}' AND form_menu_description IS NOT NULL"); if ($pretty_form_name_result) { $form_name_row = db_fetch_assoc($pretty_form_name_result); db_free_result($pretty_form_name_result); } /** * subjects with locked forms */
foreach ($raw_data_rows AS $raw_data_row) { $this_row_array = explode(': ', $raw_data_row); $data_array[$this_row_array[0]] = $this_row_array[1]; } ksort($data_array); d($data_array); /** * we don't want to duplicate queries * if the result is excluded or has a query history, ignore it */ if (!$result['exclude']) { d($history); //$data_row['monitor'] = $result['record'] & 1 ? 'dianne_mattingly' : 'wendy_robertson'; $data_row['subjid'] = quote_wrap($result['record']); $data_row['usubjid'] = quote_wrap(get_single_field($result['record'], PROJECT_ID, $Proj->firstEventId, 'dm_usubjid', '')); $data_row['event'] = quote_wrap(REDCap::getEventNames(false, false, $result['event_id'])); //$data_row['field'] = quote_wrap($Proj->metadata[$field]['element_label']); //$data_row['data'] = quote_wrap(strip_tags(str_replace('<br>', ', ', $result['data_display']))); foreach ($data_array AS $key => $val) { $data_row[quote_wrap($Proj->metadata[$key]['element_label'] . " [$key]")] = quote_wrap($val); } $data_row['description'] = quote_wrap($rule_info['name']); $data_row["Queries on $field"] = quote_wrap(count($history)); $row_csv = implode(',', $data_row) . "\n"; $table_csv .= $row_csv; } } } $headers = implode(',', array_keys($data_row)) . "\n"; if (!$debug) { create_download($lang, $app_title, $userid, $headers, $user_rights, $table_csv, '', $parent_chkd_flds, $project_id, substr(camelCase($rule_info['name']), 0, 20) . "_REPORT_", $debug, $rule_info['name']);
$this_form_name = $Proj->metadata[$_POST['field_name']]['form_name']; $event_result = db_query("SELECT DISTINCT forms.event_id FROM (SELECT * FROM redcap_events_forms) forms LEFT OUTER JOIN (SELECT * FROM redcap_events_metadata) events_meta ON forms.event_id = events_meta.event_id LEFT OUTER JOIN (SELECT * FROM redcap_events_arms) arm ON arm.arm_id = events_meta.arm_id WHERE arm.project_id = '$project_id' AND forms.form_name = '$this_form_name'"); if ($event_result) { while ($events_row = db_fetch_assoc($event_result)) { $events[] = $events_row['event_id']; } $data = REDCap::getData('array', '', array($_POST['field_name'], $this_form_name . '_complete'), $events); $form_complete = isset($_POST['form_complete']) && $_POST['form_complete'] == 'on' ? true : false; //d($data); foreach ($data AS $subject_id => $subject) { foreach ($subject AS $event_id => $event) { $do_if_complete = $form_complete ? $event[$this_form_name . '_complete'] == '2' : true; $all_fields_hidden = $my_branching_logic->allFieldsHidden($subject_id, $event_id, array($_POST['field_name'])); //d($event); if (!$all_fields_hidden && $event[$_POST['field_name']] != $_POST['default_value'] && $do_if_complete) { update_field_compare($subject_id, $project_id, $event_id, $_POST['default_value'], $event[$_POST['field_name']], $_POST['field_name'], $debug); } } } } } else { print "<h3>You must select field name and default value</h3>";
$pretty_field_names['cirr_suppfa_cirrstat'] = 'Cirrhosis status'; $pretty_field_names['plt_suppfa_faorres'] = 'Platelets <140K'; $pretty_field_names['livbp_faorres'] = 'Fibrosis score (adjusted)'; /** * WORKING DATA */ $pts = array(); $table_csv = ""; $fields = array_merge(array('cirr_suppfa_cirrstat'), $fields, array('plt_suppfa_faorres')); $pt_result = db_query("SELECT DISTINCT record FROM redcap_data WHERE project_id = '$project_id' AND field_name = 'cirr_suppfa_cirrstat' AND value != '' ORDER BY abs(record) ASC"); if ($pt_result) { while ($pt_row = db_fetch_assoc($pt_result)) { $pts[] = $pt_row['record']; } } $data = REDCap::getData('array', $pts, $fields); foreach ($data AS $subject_id => $subject) { $data_row = array(); $data_row['subjid'] = $subject_id; foreach ($subject AS $event_id => $event) { /** * if ishak or unknown scales were used, adjust the scale value */ if ($event['livbp_facat'] == 'ISHAK' || $event['livbp_facat'] == 'UNKNOWN') { if ($event['livbp_faorres'] >= '5') { $event['livbp_faorres'] = '4'; } elseif ($event['livbp_faorres'] == '3' || $event['livbp_faorres'] == '4') { $event['livbp_faorres'] = '3'; } } switch ($event['fib_lbtest']) {
/** * do stuff */ if ($debug) { if (!is_form_locked($record, $instrument, $redcap_event_name)) { d(is_t_complete($record, $event_id), $redcap_event_name); } global $Proj, $project_id; $today = date("Y-m-d"); $fields = array(); $arms = get_arms(array_keys($Proj->eventsForms)); d($arms); $baseline_event_id = $Proj->firstEventId; $tx_duration = get_single_field($record, $project_id, $baseline_event_id, 'trt_exdur', null); $tx_duration = substr($tx_duration, strpos($tx_duration, 'P') + 1, strlen($tx_duration) - 2); $tx_first_event = array_search_recursive($tx_duration . ' Weeks', $arms) !== false ? array_search_recursive($tx_duration . ' Weeks', $arms) : null; $survey_event_ids = $Proj->getEventsByArmNum($arms[$tx_first_event]['arm_num']); d($survey_event_ids); foreach ($survey_event_ids as $survey_event_id) { $survey_event_name = $Proj->getUniqueEventNames($survey_event_id); $survey_prefix = substr($survey_event_name, 0, strpos($survey_event_name, '_')); $fields[] = $survey_prefix . '_completed'; $fields[] = $survey_prefix . '_date'; $fields[] = $survey_prefix . '_startdate'; $fields[] = $survey_prefix . '_deadline'; $fields[] = $survey_prefix . '_missed'; } d($fields); $data = REDCap::getData('array', $record, $fields, $baseline_event_id); d($data); }
if (!in_array($field, array('ae_aeterm', 'ae_oth_aeterm'))) { $desc_array[] = get_field_label($field, $project_id) . ': <strong>' . $item . "</strong>"; } } } } if ($event['ae_aestdtc'] != '') { $eventAtts[] = get_event_array($event['ae_aestdtc'], $event['ae_aeendtc'], '', implode("<br />", $desc_array), $event['ae_aeterm'], $color, '', $ae_url); } } } /** * transplants */ $fields = array('livtrp_cestdtc'); $data = REDCap::getData('array', $subjid, $fields); foreach ($data AS $subject) { $url = APP_PATH_WEBROOT_FULL . "redcap_v" . $redcap_version . "/DataEntry/index.php?pid=$project_id&page=onpost_tx_liver_transplant&id=$subjid&event_id=$event_id"; $desc_array = array(); foreach ($subject AS $event_id => $event) { $eventAtts[] = get_event_array($event['livtrp_cestdtc'], '', '', '', 'Liver Transplant', 'blue', '', $url, ''); } } /** * generate and return JSON to timeline script. */ if (isset($subjid)) { $json_data = array( //Timeline attributes 'dateTimeFormat' => 'Gregorian', //JSON! //Event attributes
show_var($data_quality_status_query); } } } /** * flush and log any '' values for $field_name */ $find_blank_values_query = "SELECT record, event_id FROM redcap_data WHERE project_id = '$project_id' AND field_name = '$field_name' AND value = ''"; $find_blanks_result = db_query($find_blank_values_query); if ($find_blanks_result) { while ($found_blank_row = db_fetch_assoc($find_blanks_result)) { $delete_blank_values_query = "DELETE FROM redcap_data WHERE project_id = '$project_id' AND field_name = '$field_name' AND record = '{$found_blank_row['record']}' AND event_id = '{$found_blank_row['event_id']}' AND value = ''"; if (!$debug) { if (db_query($delete_blank_values_query)) { //target_log_event($delete_blank_values_query, 'redcap_data', 'delete', $subject_id, "$field_name = ''", "Delete blank $field_name", '', $project_id); REDCap::logEvent("Delete blank $field_name", "$field_name = ''", $delete_blank_values_query, $found_blank_row['record'], $found_blank_row['event_id']); } else { error_log(db_error() . ': ' . $delete_blank_values_query); echo(db_error() . ": " . $delete_blank_values_query . "<br />"); } } else { show_var($delete_blank_values_query); } } db_free_result($find_blanks_result); } } else { print "<h3>You must select both a source (existing) and destination (new) field.</h3>"; } $timer_stop = microtime(true); $timer_time = number_format(($timer_stop - $timer_start), 2);