<?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';
/** * @param $record * @param $event_id * @param $group_id * @param $debug */ public static 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 = Prioritize::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); } } } 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); } } } 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); } }
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';
$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)); }
public function notify($title) { global $redcap_version; $dark = "#800000"; //#1a74ba 1a74ba $light = "#FFE1E1"; //#ebf6f3 $border = "#800000"; //FF0000"; //#a6d1ed #3182b9 // Run notification $url = APP_PATH_WEBROOT_FULL . "redcap_v{$redcap_version}/" . "DataEntry/index.php?pid={$this->project_id}&page={$this->instrument}&id={$this->record}&event_id={$this->event_id}"; // Message (email html painfully copied from box.net notification email) $msg = RCView::table(array('cellpadding' => '0', 'cellspacing' => '0', 'border' => '0', 'style' => 'border:1px solid #bbb; font:normal 12px Arial;color:#666'), RCView::tr(array(), RCView::td(array('style' => 'padding:13px'), RCView::table(array('style' => 'font:normal 15px Arial'), RCView::tr(array(), RCView::td(array('style' => 'font-size:18px;color:#000;border-bottom:1px solid #bbb'), RCView::span(array('style' => 'color:black'), RCVieW::a(array('style' => 'color:black'), 'REDCap AutoNotification Alert')) . RCView::br())) . RCView::tr(array(), RCView::td(array('style' => 'padding:10px 0'), RCView::table(array('style' => 'font:normal 12px Arial;color:#666'), RCView::tr(array(), RCView::td(array('style' => 'text-align:right'), "Title") . RCView::td(array('style' => 'padding-left:10px;color:#000'), RCView::span(array('style' => 'color:black'), RCView::a(array('style' => 'color:black'), "<b>{$title}</b>")))) . RCView::tr(array(), RCView::td(array('style' => 'text-align:right'), "Project") . RCView::td(array('style' => 'padding-left:10px;color:#000'), RCView::span(array('style' => 'color:black'), RCView::a(array('style' => 'color:black'), REDCap::getProjectTitle())))) . ($this->redcap_event_name ? RCView::tr(array(), RCView::td(array('style' => 'text-align:right'), "Event") . RCView::td(array('style' => 'padding-left:10px;color:#000'), RCView::span(array('style' => 'color:black'), RCView::a(array('style' => 'color:black'), "{$this->redcap_event_name}")))) : '') . RCView::tr(array(), RCView::td(array('style' => 'text-align:right'), "Instrument") . RCView::td(array('style' => 'padding-left:10px;color:#000'), RCView::span(array('style' => 'color:black'), RCView::a(array('style' => 'color:black'), $this->instrument)))) . RCView::tr(array(), RCView::td(array('style' => 'text-align:right'), "Record") . RCView::td(array('style' => 'padding-left:10px;color:#000'), RCView::span(array('style' => 'color:black'), RCView::a(array('style' => 'color:black'), $this->record)))) . RCView::tr(array(), RCView::td(array('style' => 'text-align:right'), "Date/Time") . RCView::td(array('style' => 'padding-left:10px;color:#000'), RCView::span(array('style' => 'color:black'), RCView::a(array('style' => 'color:black'), date('Y-m-d H:i:s'))))) . RCView::tr(array(), RCView::td(array('style' => 'text-align:right'), "Message") . RCView::td(array('style' => 'padding-left:10px;color:#000'), RCView::span(array('style' => 'color:black'), RCView::a(array('style' => 'color:black'), $this->config['message']))))))) . RCView::tr(array(), RCView::td(array('style' => "border:1px solid {$border};background-color:{$light};padding:20px"), RCView::table(array('style' => 'font:normal 12px Arial', 'cellpadding' => '0', 'cellspacing' => '0'), RCView::tr(array('style' => 'vertical-align:middle'), RCView::td(array(), RCView::table(array('cellpadding' => '0', 'cellspacing' => '0'), RCView::tr(array(), RCView::td(array('style' => "border:1px solid #600000;background-color:{$dark};padding:8px;font:bold 12px Arial"), RCView::a(array('class' => 'hide', 'style' => 'color:#fff;white-space:nowrap;text-decoration:none', 'href' => $url), "View Record"))))) . RCView::td(array('style' => 'padding-left:15px'), "To view this record, visit this link:" . RCView::br() . RCView::a(array('style' => "color:{$dark}", 'href' => $url), $url)))))))))); $msg = "<HTML><head></head><body>" . $msg . "</body></html>"; // Determine number of emails to send // Prepare message $email = new Message(); $email->setTo($this->config['to']); $email->setFrom($this->config['from']); $email->setSubject($this->config['subject']); $email->setBody($msg); // Send Email if (!$email->send()) { error_log('Error sending mail: ' . $email->getSendError() . ' with ' . json_encode($email)); exit; } // error_log ('Email sent'); // Add Log Entry $data_values = "title,{$title}\nrecord,{$this->record}\nevent,{$this->redcap_event_name}"; REDCap::logEvent('AutoNotify Alert', $data_values); }
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);
// Create temp file - Set the target file to be saved in the temp dir (set timestamp in filename as 1 hour from now so that it gets deleted automatically in 1 hour) $inOneHour = date("YmdHis", mktime(date("H")+1,date("i"),date("s"),date("m"),date("d"),date("Y"))); $target_filename = "{$inOneHour}_pid{$project_id}_".generateRandomHash(6).".csv"; $target_file = APP_PATH_TEMP . $target_filename; echo RCView::div(array('class'=>'round chklist','id'=>'Large Data Export'), RCView::div(array('class'=>'chklisthdr','style'=>'color:rgb(128,0,0);margin-top:10px;'), "Exporting Complete CSV"). RCView::p(array(),"Breaking $id_count records into $batch_total batch exports..."). RCView::div(array('id'=>'progress','style'=>'width:600px;border:1px solid #ccc;margin-bottom:10px;')). RCView::div(array('id'=>'progress_info','style'=>'width')) ); if (!$debug) { // Start Export REDCap::logEvent("Full Export Requested"); $fh = fopen($target_file, 'w') or die("can't open file"); $time_start = microtime(true); $batch_times = array(); foreach ($batches as $b => $batch) { print "<pre>Batch $b starts at " . $batch[0] . "</pre>"; $batch_start = microtime(true); if (!empty($batch_times)) { // Calculate projected time remaining $batch_avg = floatval(array_sum($batch_times) / count($batch_times)); $batch_remaining = intval($batch_total - count($batch_times)); $time_remaining = round($batch_remaining * $batch_avg); $time_remaining_msg = "Approximately " . $time_remaining . " seconds remaining..."; } $percent = intval(($b+1)/$batch_total * 100).'%'; $msg = "Processing batch " . ($b + 1) . " of $batch_total.";
/** * LongitudinalReports::save * @param type $saveReportsArray an array of report config parameters rptid => p1 = v1, p2 = v2 * @return boolean */ public static function save($saveReportsArray) { $success = true; $saveArray = array(); // Add 'event' level so array is in format expected by REDCap::saveData foreach ($saveReportsArray as $rptParams) { $saveArray[$rptParams['report_id']][] = $rptParams; } $result = REDCap::saveData(LR_REPORT_DATA_PROJECT_ID, 'array', $saveArray, 'overwrite'); if (isset($result['errors']) && count($result['errors']) > 0) { $success = false; REDCap::logEvent('Longitudinal Reports save failed', print_r($result['errors'], true) . PHP_EOL . ' ' . print_r($saveArray, true)); } return $success; }
<?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']; //$report = LongitudinalReports::getReports($report_id); //if (empty($report)) exit('0'); // Copy the report and return the new report_id $new_report_id = LongitudinalReports::copyReport($report_id); if ($new_report_id === false) { exit('0'); } REDCap::logEvent("Copy longitudinal report", "report_id = {$report_id}, new_report_id = {$new_report_id}"); // Return HTML of updated report list and report_id print json_encode(array('new_report_id' => $new_report_id, 'html' => LongitudinalReports::renderReportList()));