<?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';
// Get html report table
list($report_table, $num_results_returned) = LongitudinalReports::doReport($_POST['report_id'], 'report', 'html', false, false, false, false, false, false, false, false, false, false, false, isset($_GET['instruments']) ? explode(',', $_GET['instruments']) : array(), isset($_GET['events']) ? explode(',', $_GET['events']) : array());
// Display report and title and other text
print "<div id='report_div' style='margin:10px 0 20px;'>" . RCView::div(array('style' => ''), RCView::div(array('class' => 'hide_in_print', 'style' => 'float:left;width:350px;'), RCView::div(array('style' => 'font-weight:bold;'), $lang['custom_reports_02'] . RCView::span(array('style' => 'margin-left:5px;color:#800000;font-size:15px;'), User::number_format_user($num_results_returned))) . RCView::div(array('style' => ''), $lang['custom_reports_03'] . RCView::span(array('style' => 'margin-left:5px;'), User::number_format_user(LongitudinalRecords::getRecordCount())) . (!$longitudinal ? "" : RCView::div(array('style' => 'margin-top:3px;color:#888;font-size:11px;font-family:tahoma,arial;'), $lang['custom_reports_09'])))) . RCView::div(array('class' => 'hide_in_print', 'style' => 'float:left;'), ($user_rights['data_export_tool'] == '0' ? '' : RCView::button(array('class' => 'report_btn jqbuttonmed', 'onclick' => "showExportFormatDialog('{$_POST['report_id']}');", 'style' => 'font-size:11px;padding:1px 4px 0px !important;'), RCView::img(array('src' => 'go-down.png', 'style' => 'vertical-align:middle;')) . RCView::span(array('style' => 'vertical-align:middle;'), $lang['custom_reports_12']))) . RCView::SP . RCView::button(array('class' => 'report_btn jqbuttonmed', 'onclick' => "window.print();", 'style' => 'font-size:11px;padding:1px 4px 0px !important;'), RCView::img(array('src' => 'printer.png', 'style' => 'vertical-align:middle;')) . RCView::span(array('style' => 'vertical-align:middle;'), $lang['custom_reports_13'])) . RCView::SP . ($_POST['report_id'] == 'ALL' || $_POST['report_id'] == 'SELECTED' || !$user_rights['reports'] ? '' : RCView::button(array('class' => 'report_btn jqbuttonmed', 'onclick' => "window.location.href = '" . APP_PATH_WEBROOT . LR_PATH_FROM_WEBROOT . "index.php?pid=" . PROJECT_ID . "&report_id={$_POST['report_id']}&addedit=1';", 'style' => 'font-size:11px;padding:1px 4px 0px !important;'), RCView::img(array('src' => 'pencil_small.png', 'style' => 'vertical-align:middle;')) . RCView::span(array('style' => 'vertical-align:middle;'), $lang['custom_reports_14'])))) . RCView::div(array('class' => 'clear'), '')) . RCView::div(array('id' => 'this_report_title', 'style' => 'margin:40px 0 8px;padding:5px 3px;color:#800000;font-size:18px;font-weight:bold;'), LongitudinalReports::getReportNames($_POST['report_id'])) . $report_table . "</div>";
 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);
 }