if ($empty_result) { while ($empty_row = db_fetch_assoc($empty_result)) { $history = Form::getDataHistoryLog($empty_row['record'], $empty_row['event_id'], $empty_row['field_name']); $all_fields_hidden = $my_branching_logic->allFieldsHidden($empty_row['record'], $empty_row['event_id'], array($empty_row['field_name'])); if ($debug) { /** * pick apart the hidden field logic - something's not right with fib_lbtest logic. ?'null'? */ $fieldsDependent = getDependentFields(array($empty_row['field_name']), false, true); $unique_event_name = $project->getUniqueEventNames($empty_row['event_id']); $record_data = Records::getSingleRecordData($empty_row['record'], array_merge($fieldsDependent, array($empty_row['field_name']))); $logic = $project->metadata[$empty_row['field_name']]['branching_logic']; if ($longitudinal) { $logic = LogicTester::logicPrependEventName($logic, $unique_event_name); } if (LogicTester::isValid($logic)) { $displayField = LogicTester::apply($logic, $record_data); $displayField = $displayField ? false : true; } show_var($fieldsDependent, 'DEP FIELDS'); show_var($unique_event_name, 'unique event name'); show_var($record_data, 'record data'); show_var($logic, 'logic'); show_var($displayField, 'all hidden?'); } /** * if all values are hidden for this field, delete the row. */ if ($all_fields_hidden) { $rows_deleted++; $delete_query = "DELETE FROM redcap_data WHERE record = '{$empty_row['record']}' AND project_id = '$project_id' AND event_id = '{$empty_row['event_id']}' AND field_name = '{$empty_row['field_name']}' AND value = '" . prep($empty_row['value']) . "'";
'family_members_grandchildren' => "[enrollment_arm_1][family_members_grandchildren]='1'", 'family_members_other_affected_relatives' => "[enrollment_arm_1][have_family_info]='1'" ); Andrew Martin Stanford University **/ global $end_survey_redirect_next_survey, $end_survey_redirect_url; //hook_log($auto_continue_logic, "DEBUG", "Starting AutoContinueLogic!"); // Check if custom logic is applied to this instrument if (isset($auto_continue_logic[$instrument])) { //hook_log("Applying auto-continue-logic to $instrument","DEBUG"); // Get the logic and evaluate it $raw_logic = $auto_continue_logic[$instrument]; $isValid = LogicTester::isValid($raw_logic); if (!$isValid) { print "<div class='red'><h3><center>Supplied survey auto-continue logic is invalid:<br>{$raw_logic}</center></h3></div>"; hook_log("AutoContinue Logic is INVALID for {$project_id} / {$instrument}: {$raw_logic}", "ERROR"); } $logic_result = LogicTester::evaluateLogicSingleRecord($raw_logic, $record); if ($logic_result == false) { // This instrument should not be taken! hook_log("AutoContinue Logic is FALSE - skipping {$instrument}", "DEBUG"); // If autocontinue is enabled - then redirect to next instrument if ($end_survey_redirect_next_survey) { // Try to get the next survey url $next_survey_url = Survey::getAutoContinueSurveyUrl($record, $instrument, $event_id); //print "Redirecting you to $next_survey_url"; hook_log("Redirecting {$record} from {$instrument} to {$next_survey_url}", "DEBUG"); redirect($next_survey_url);
public function testLogic($logic) { logIt('testLogic: ' . $logic); if (LogicTester::isValid($logic)) { // Append current event details if (REDCap::isLongitudinal() && $this->redcap_event_name) { $logic = LogicTester::logicPrependEventName($logic, $this->redcap_event_name); } // Test logic logIt('Logic:' . $logic, 'DEBUG'); if (LogicTester::evaluateLogicSingleRecord($logic, $this->record)) { $result = RCView::img(array('class' => 'imgfix', 'src' => 'accept.png')) . " True"; } else { $result = RCView::img(array('class' => 'imgfix', 'src' => 'cross.png')) . " False"; } } else { $result = RCView::img(array('class' => 'imgfix', 'src' => 'error.png')) . " Invalid Syntax"; } return $result; }
public static function doReport($report_id = '0', $outputType = 'report', $outputFormat = 'html', $apiExportLabels = false, $apiExportHeadersAsLabels = false, $outputDags = false, $outputSurveyFields = false, $removeIdentifierFields = false, $hashRecordID = false, $removeUnvalidatedTextFields = false, $removeNotesFields = false, $removeDateFields = false, $dateShiftDates = false, $dateShiftSurveyTimestamps = false, $selectedInstruments = array(), $selectedEvents = array(), $returnIncludeRecordEventArray = false, $outputCheckboxLabel = false) { global $Proj, $user_rights, $isAjax, $app_title, $lang, $redcap_version; // Check report_id if (!is_numeric($report_id) && $report_id != 'ALL' && $report_id != 'SELECTED') { exit($isAjax ? '0' : 'ERROR'); } // Increase memory limit in case needed for intensive processing if (str_replace("M", "", ini_get('memory_limit')) < 1024) { ini_set('memory_limit', '1024M'); } // TESTING // if (isDev()) ini_set('memory_limit', '12M'); // Determine if this is API report export $isAPI = PAGE == 'api/index.php' || PAGE == 'API/index.php'; // Set flag to ALWAYS archive exported files in File Repository $archiveFiles = true; // Get report attributes $report = self::getReports($report_id, $selectedInstruments, $selectedEvents); if (empty($report)) { if ($isAPI) { exit(RestUtility::sendResponse(400, 'The value of the parameter "report_id" is not valid')); } else { exit($isAjax ? '0' : 'ERROR'); } } // Check user rights: Does user have access to this report? (exclude super users in this check) if (defined('SUPER_USER') && !SUPER_USER || !defined('SUPER_USER')) { // If user has Add/Edit Report rights then let them view this report, OR if they have explicit rights to this report if (self::getReportNames($report_id, !$user_rights['reports']) == null) { // User does NOT have access to this report AND also does not have Add/Edit Report rights if ($isAPI) { exit(RestUtility::sendResponse(403, "User \"" . USERID . "\" does not have access to this report.")); } else { exit($isAjax ? '0' : 'ERROR'); } } } // Determine if a report or an export $outputType = $outputType == 'report' ? 'report' : 'export'; if ($outputType != 'report') { $returnIncludeRecordEventArray = false; } // Determine whether to output a stats syntax file $stats_packages = array('r', 'spss', 'stata', 'sas'); // $outputSyntaxFile = (in_array($outputFormat, $stats_packages)); // If CSV, determine whether to output a stats syntax file $outputAsLabels = $outputFormat == 'csvlabels'; $outputHeadersAsLabels = $outputFormat == 'csvlabels'; // List of fields to export $fields = $report['fields']; // If removing any fields due to DE-IDENTIFICATION, loop through them and remove them if ($removeIdentifierFields || $removeUnvalidatedTextFields || $removeNotesFields || $removeDateFields) { foreach ($fields as $key => $this_event_field) { $this_field = self::getFieldFromEventField($this_event_field); // Skip record ID field if ($this_field == $Proj->table_pk) { continue; } // Get field type and validation type $this_field_type = $Proj->metadata[$this_field]['element_type']; $this_val_type = $Proj->metadata[$this_field]['element_validation_type']; $this_phi = $Proj->metadata[$this_field]['field_phi']; // Check if needs to be removed if ($this_phi && $removeIdentifierFields || $this_field_type == 'text' && $this_val_type == '' && $removeUnvalidatedTextFields || $this_field_type == 'textarea' && $removeNotesFields || $this_field_type == 'text' && $removeDateFields && substr($this_val_type, 0, 4) == 'date') { // Remove the field from $fields unset($fields[$key]); } } } // List of events to export $events = $report['limiter_events']; // Limit to user's DAG (if user is in a DAG), and if not in a DAG, then limit to the DAG filter $userInDAG = isset($user_rights['group_id']) && is_numeric($user_rights['group_id']); $dags = $userInDAG ? $user_rights['group_id'] : $report['filter_dags']; // Set options to include DAG names and/or survey fields (exclude ALL and SELECTED pre-defined reports) if (is_numeric($report_id)) { $outputDags = $report['output_dags'] == '1'; $outputSurveyFields = $report['output_survey_fields'] == '1'; } elseif (!is_numeric($report_id) && $outputType == 'report') { $outputDags = $outputSurveyFields = true; } // If user is in a DAG, then do not output the DAG name field if ($userInDAG) { $outputDags = false; } // If we're removing identifier fields, then also remove Survey Identifier (if outputting survey fields) $outputSurveyIdentifier = $outputSurveyFields && !$removeIdentifierFields; $outputScheduleDates = $report['output_schedule_dates']; $outputSurveyUrls = $report['output_survey_urls']; // File names for archived file $today_hm = date("Y-m-d_Hi"); $projTitleShort = substr(str_replace(" ", "", ucwords(preg_replace("/[^a-zA-Z0-9 ]/", "", html_entity_decode($app_title, ENT_QUOTES)))), 0, 20); if ($outputFormat == 'r' || $outputFormat == 'csvraw') { // CSV with header row $csv_filename = $projTitleShort . "_DATA_" . $today_hm . ".csv"; } elseif ($outputFormat == 'csvlabels') { // CSV labels $csv_filename = $projTitleShort . "_DATA_LABELS_" . $today_hm . ".csv"; } else { // CSV without header row $csv_filename = $projTitleShort . "_DATA_NOHDRS_" . $today_hm . ".csv"; } // Build sort array of sort fields and their attribute (ASC, DESC) $sortArray = array(); if ($report['orderby_field1'] != '') { $sortArray[$report['orderby_field1']] = $report['orderby_sort1']; } if ($report['orderby_field2'] != '') { $sortArray[$report['orderby_field2']] = $report['orderby_sort2']; } if ($report['orderby_field3'] != '') { $sortArray[$report['orderby_field3']] = $report['orderby_sort3']; } // If the only sort field is record ID field, then remove it (because it will sort by record ID and event on its own) if (count($sortArray) == 1 && isset($sortArray[$Proj->table_pk]) && $sortArray[$Proj->table_pk] == 'ASC') { unset($sortArray[$Proj->table_pk]); } ## BUILD AND STORE CSV FILE // Set output format (CSV or HTML or API format) if ($isAPI) { // For API report export, return in desired format $returnDataFormat = $outputFormat; $outputAsLabels = $apiExportLabels; $outputHeadersAsLabels = $apiExportHeadersAsLabels; } elseif ($outputType == 'report') { // For webpage report, return html $returnDataFormat = 'html'; } else { $returnDataFormat = 'csv'; } // Check syntax of logic string: If there is an issue in the logic, then return false and stop processing if ($outputType == 'report' && $report['limiter_logic'] != '' && !LogicTester::isValid($report['limiter_logic'])) { return array(RCView::div(array('class' => 'red'), RCView::img(array('src' => 'exclamation.png', 'class' => 'imgfix')) . RCView::b($lang['global_01'] . $lang['colon']) . " " . $lang['report_builder_132']), 0); } // Retrieve CSV data file $data_content = LongitudinalRecords::getData(PROJECT_ID, $returnDataFormat, array(), $fields, $events, $dags, false, $outputDags, $outputSurveyFields, $report['limiter_logic'], $outputAsLabels, $outputHeadersAsLabels, $hashRecordID, $dateShiftDates, $dateShiftSurveyTimestamps, $sortArray, $outputType != 'report', true, $returnIncludeRecordEventArray, true, $outputSurveyIdentifier, $outputCheckboxLabel, $outputScheduleDates, $outputSurveyUrls); // Replace any MS Word chacters in the data (from 6.12.0 string passed by ref) if (version_compare($redcap_version, '6.12.0', '<')) { $data_content = replaceMSchars($data_content); } else { //replaceMSchars(is_array($data_content) ? $data_content[0] : $data_content); //"Only variables can be passed by reference" if (is_array($data_content)) { replaceMSchars($data_content[0]); } else { replaceMSchars($data_content); } } ## Logging (for exports only) if ($outputType != 'report' || $isAPI) { // Set data_values as JSON-encoded $data_values = array('report_id' => $report_id, 'export_format' => substr($outputFormat, 0, 3) == 'csv' ? 'CSV' : strtoupper($outputFormat), 'rawOrLabel' => $outputAsLabels ? 'label' : 'raw'); if ($outputDags) { $data_values['export_data_access_group'] = 'Yes'; } if ($outputSurveyFields) { $data_values['export_survey_fields'] = 'Yes'; } if ($dateShiftDates) { $data_values['date_shifted'] = 'Yes'; } if (isset($user_rights['data_export_tool']) && $user_rights['data_export_tool'] == '2') { $data_values['deidentified'] = 'Yes'; } if (isset($user_rights['data_export_tool']) && $user_rights['data_export_tool'] == '3') { $data_values['removed_identifiers'] = 'Yes'; } $data_values['fields'] = empty($fields) ? array_keys($Proj->metadata) : $fields; // Log it log_event("", "redcap_data", "longitudinal_report", "", json_encode($data_values), "Longitudinal Report" . ($isAPI ? " (API)" : "")); } // IF OUTPUTTING A REPORT, RETURN THE CONTENT HERE if ($outputType == 'report' || $isAPI) { return $data_content; } // For SAS, SPSS, and Stata, remove the CSV file's header row if (in_array($outputFormat, array('spss', 'stata', 'sas'))) { // Remove header row list($headers, $data_content) = explode("\n", $data_content, 2); } // Store the data file $data_edoc_id = self::storeExportFile($csv_filename, $data_content, $archiveFiles, $dateShiftDates); if ($data_edoc_id === false) { return false; } /* Stats syntax not implemented for Longitudinal Reports ## BUILD AND STORE SYNTAX FILE (if applicable) // If exporting to a stats package, then also generate the associate syntax file for that package $syntax_edoc_id = null; if ($outputSyntaxFile) { // Generate syntax file $syntax_file_contents = self::getStatsPackageSyntax($outputFormat, $fields, $csv_filename, $outputDags, $outputSurveyFields, $removeIdentifierFields); // Set the filename of the syntax file if ($outputFormat == 'spss') { $stats_package_filename = $projTitleShort ."_" . strtoupper($outputFormat) . "_$today_hm.sps"; } elseif ($outputFormat == 'stata') { $stats_package_filename = $projTitleShort ."_" . strtoupper($outputFormat) . "_$today_hm.do"; } else { $stats_package_filename = $projTitleShort ."_" . strtoupper($outputFormat) . "_$today_hm.$outputFormat"; } // Store the syntax file $syntax_edoc_id = self::storeExportFile($stats_package_filename, $syntax_file_contents, $archiveFiles, $dateShiftDates); if ($syntax_edoc_id === false) return false; } */ $syntax_edoc_id = null; // Return the edoc_id's of the CSV data file return array($data_edoc_id, $syntax_edoc_id); }