Skip to content

Commit

Permalink
6.3.1
Browse files Browse the repository at this point in the history
  • Loading branch information
scottjpearson committed Dec 12, 2023
1 parent b5fbac0 commit 38b99f1
Show file tree
Hide file tree
Showing 24 changed files with 814 additions and 337 deletions.
5 changes: 2 additions & 3 deletions CareerDev.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class CareerDev {
public static $passedModule = NULL;

public static function getVersion() {
return "6.3.0";
return "6.3.1";
}

public static function getLockFile($pid) {
Expand Down Expand Up @@ -1164,8 +1164,7 @@ public static function getMenu($menuName, $pid = NULL) {
$switches = new FeatureSwitches($token, $server, $pid);
$ary = [];
if (self::has("mentoring_agreement", $pid) && $switches->isOnForProject("Mentee-Mentor")) {
$ary["Configure Mentee-Mentor Agreements"] = self::link("/mentor/config.php");
$ary["Add Mentors for Existing Scholars"] = self::link("addMentor.php");
$ary["Start Mentee-Mentor Agreements"] = self::link("/mentor/config.php");
$ary["Mentee-Mentor Agreements Dashboard"] = self::link("/mentor/dashboard.php");
}
$ary = array_merge($ary, [
Expand Down
2 changes: 1 addition & 1 deletion FlightTrackerExternalModule.php
Original file line number Diff line number Diff line change
Expand Up @@ -1276,7 +1276,7 @@ function cron() {
}
}

public function preprocessScholarPortalData($pids) {
public function preprocessScholarPortalPersonalData($pids) {
foreach ($pids as $pid) {
CareerDev::setPid($pid);
Application::log("Preprocessing lists for Scholar Portal", $pid);
Expand Down
35 changes: 34 additions & 1 deletion charts/grantTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@

$title = "Make a Table of Grants";
if (!isset($_GET['cohort']) || !$_GET['cohort']) {
if (isset($_GET['NOAUTH'])) {
die("Improper access!");
}
require_once(__DIR__."/../charts/baseWeb.php");

$cohorts = new Cohorts($token, $server, Application::getModule());
Expand Down Expand Up @@ -115,24 +118,54 @@
}

if (isset($_GET['csv'])) {
if (isset($_GET['NOAUTH'])) {
die("Improper access!");
}
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="grants.csv"');
$fp = fopen("php://output", "w");
foreach ($ary as $line) {
fputcsv($fp, $line);
}
fclose($fp);
} else if (isset($_GET['json'])) {
$myToken = Application::getSetting("grant_table_token", $pid);
$data = [];
# The token protects the NOAUTH from nefarious access
if ($myToken && ($myToken == $_GET['json'])) {
for ($i = 1; $i < count($ary); $i++) {
$dataRow = [];
$row = $ary[$i];
for ($j = 0; $j < count($headers); $j++) {
$header = $headers[$j];
$dataRow[$header] = REDCapManagement::clearUnicode($row[$j]);
}
$data[] = $dataRow;
}
}
echo json_encode($data);
} else {
if (isset($_GET['NOAUTH'])) {
die("Improper access!");
}
require_once(__DIR__."/../charts/baseWeb.php");

# if this is used widely, a reset token feature might be needed to enhance security
$myToken = Application::getSetting("grant_table_token", $pid);
if (!$myToken) {
$myToken = REDCapManagement::makeHash(16);
Application::saveSetting("grant_table_token", $pid);
}

$thisLink = $_SERVER['REQUEST_URI'] ?? Application::link("this");
$headers = $ary[0];
echo "<h1>$title</h1>";
if ($cohort) {
echo "<h2>Cohort $cohort</h2>";
}
echo $dates ? "<p class='centered'>$dates</p>" : "";
echo "<p class='centered'><a href='$thisLink&csv'>Download as CSV</a></p>";
echo "<p class='centered'><a href='$thisLink&csv'>Download as CSV</a><br/>";
echo "<a href='$thisLink&json=$myToken&NOAUTH'>Access as a JSON (Dynamically Updated)</a></p>";
echo "<p class='centered max-width'>Note: Budget dates are the dates that we have financial data for. Project dates are the prospective dates of the entire project.</p>";
echo "<table class='bordered'>";
echo "<thead><tr>";
Expand Down
4 changes: 2 additions & 2 deletions classes/Crons.php
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,7 @@ private static function getBatchQueueFromDB() {
}

private static function getNewIndex($prefix) {
$i = 0;
$i = 1;
while (
Application::getSystemSetting($prefix.$i)
&& ($i < self::MAX_BATCHES_IN_QUEUE)
Expand Down Expand Up @@ -487,7 +487,7 @@ private static function addRunJobToDB($runJob) {
if (!$runJobs) {
$runJobs = [];
}
$index = self::getNewRunJobIndex() + 1;
$index = self::getNewRunJobIndex();
$setting = self::RUN_JOB_PREFIX.$index;
$runJobs[] = $setting;
Application::saveSystemSetting($setting, $runJob);
Expand Down
13 changes: 10 additions & 3 deletions classes/Download.php
Original file line number Diff line number Diff line change
Expand Up @@ -916,8 +916,14 @@ public static function firstnames($token, $server) {
public static function getSingleValue($pid, $recordId, $field, $instance = NULL) {
$module = Application::getModule();
$dataTable = Application::getDataTable($pid);
$sql = "SELECT value FROM $dataTable WHERE project_id = ? AND field_name = ? AND record = ? AND instance = ?";
$params = [$pid, $field, $recordId, $instance];
$sql = "SELECT value FROM $dataTable WHERE project_id = ? AND field_name = ? AND record = ?";
$params = [$pid, $field, $recordId];
if (isset($instance) && ($instance != 1)) {
$sql .= " AND instance = ?";
$params[] = $instance;
} else {
$sql .= " AND instance IS NULL";
}
$result = $module->query($sql, $params);
if ($row = $result->fetch_assoc()) {
return $row['value'];
Expand Down Expand Up @@ -1139,7 +1145,8 @@ public static function names($token, $server) {
$redcapData = self::sendToServer($server, $data);
$ordered = array();
foreach ($redcapData as $row) {
$ordered[$row['identifier_last_name'].", ".$row['identifier_first_name']." ".$row['record_id']] = $row;
# case insensitive
$ordered[strtoupper($row['identifier_last_name'].", ".$row['identifier_first_name']." ".$row['record_id'])] = $row;
}
ksort($ordered);

Expand Down
2 changes: 1 addition & 1 deletion classes/Filter.php
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,7 @@ private function getActivityCodes($rows) {

# variable => label
public function getDemographicChoices() {
# optional fields added via foreach loop below
$ary = [
"summary_gender" => "Gender",
"summary_race_ethnicity" => "Race/Ethnicity",
Expand All @@ -377,7 +378,6 @@ public function getDemographicChoices() {
"summary_current_tenure" => "Recorded Tenure Status",
// "calc_institution" => "Institution",
"summary_current_rank" => "Current Academic Rank",
"identifier_person_role" => "Person Role",
"calc_employment" => "Employment Status",
"calc_email_domain" => "Email Domain",
];
Expand Down
29 changes: 28 additions & 1 deletion classes/REDCapManagement.php
Original file line number Diff line number Diff line change
Expand Up @@ -1463,6 +1463,13 @@ public static function getPIDFromToken($token, $server) {
throw new \Exception("Could not get project-id from project settings: ".self::json_encode_with_spaces($projectSettings));
}

public static function getOptionalFieldsNumber($field) {
if (preg_match("/person_role/", $field)) {
return 6;
}
return 1;
}

public static function getSpecialFields($type, $metadata) {
$metadataFields = DataDictionaryManagement::getFieldsFromMetadata($metadata);
$fields = [];
Expand Down Expand Up @@ -1498,6 +1505,16 @@ public static function getSpecialFields($type, $metadata) {
$fields["institutions"] = ["check_institution", "init_import_institution", "followup_institution"];
$fields["optional"] = ["identifier_person_role"];

if ($type == "optional") {
$fieldsWithNumbers = [];
foreach ($fields[$type] as $redcapField) {
$numFields = self::getOptionalFieldsNumber($redcapField);
for ($i = 1; $i <= $numFields; $i++) {
$fieldsWithNumbers[] = self::getOptionalFieldSetting($redcapField, $i);
}
}
return $fieldsWithNumbers;
}
if (isset($fields[$type])) {
return $fields[$type];
}
Expand All @@ -1516,6 +1533,14 @@ public static function getOptionalFields() {
return self::getSpecialFields("optional", []);
}

# can be used for a REDCap field or an ExtMod Setting
public static function getOptionalFieldSetting($field, $i) {
if ($i == 1) {
return $field;
}
return $field."_".$i;
}

public static function getOptionalSettings() {
$fileMetadata = DataDictionaryManagement::getFileMetadata();
$fields = self::getOptionalFields();
Expand All @@ -1524,7 +1549,9 @@ public static function getOptionalSettings() {
$setting = self::turnOptionalFieldIntoSetting($field);
if ($setting) {
$row = DataDictionaryManagement::getRowForFieldFromMetadata($field, $fileMetadata);
$settings[$setting] = $row['field_label'] ?? "Optional Field";
if ($row) {
$settings[$setting] = $row['field_label'] ?? "Optional Field";
}
}
}
return $settings;
Expand Down
1 change: 1 addition & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
"wrangler/certifyPub",
"reporting/getData",
"js/xtract.js",
"charts/grantTable",
"emailMgmt/makeSurveyLinks",
"copyProject",
"reporting/tables2-4WithAuth",
Expand Down
59 changes: 44 additions & 15 deletions config.php
Original file line number Diff line number Diff line change
Expand Up @@ -375,20 +375,18 @@ function makeSettings($module, $pid) {
$fileMetadata = DataDictionaryManagement::getFileMetadata();
foreach(REDCapManagement::getOptionalFields() as $field) {
$setting = REDCapManagement::turnOptionalFieldIntoSetting($field);
$numSettings = REDCapManagement::getOptionalFieldsNumber($field);
$label = $optionSettings[$setting] ?? $field;
$row = DataDictionaryManagement::getRowForFieldFromMetadata($field, $fileMetadata);
$form = $row['form_name'] ?? "";
$note = (isset($row['field_note']) && $row['field_note']) ? "<div class='smaller'>".$row['field_note']."</div>" : "";
$ary["Administrative Setup"][] = makeSetting($setting, "short_textarea", "<div>Options for <strong>$label</strong> on the <strong>".ucfirst($form)."</strong> form.</div>$note<div class='smaller'>(One per line. Optional. When filled in, it will create an extra field in your project once you update your Data Dictionary on Flight Tracker's Home page.)</div>");
$message = "<div>Options for <strong>$label</strong> on the <strong>".ucfirst($form)."</strong> form.</div>$note<div class='smaller'>(One per line. Optional. When filled in, it will create an extra field in your project once you update your Data Dictionary on Flight Tracker's Home page.)</div>";
$ary["Administrative Setup"][] = makeOptionalSetting($setting, "short_textarea", $message, $numSettings);
}
$ary["Administrative Setup"][] = makeCheckboxes("shared_forms", FlightTrackerExternalModule::getConfigurableForms(), "In Flight Tracker's data-sharing on the same server, in addition to surveys, what data should be shared among the following forms?");


$ary["Emails"] = [];
// array_push($ary["Emails"], makeHelperText("An initial email can automatically be sent out during the first month after the new record is added to the database. If you desire to use this feature, please complete the following fields."));
// array_push($ary["Emails"], makeSetting("init_from", "text", "Initial Email From Address"));
// array_push($ary["Emails"], makeSetting("init_subject", "text", "Initial Email Subject"));
// array_push($ary["Emails"], makeSetting("init_message", "textarea", "Initial Email Message"));
$ary["Emails"][] = makeSetting("admin_email", "text", "Administrative Email(s) for Flight Tracker Project; comma-separated");
$ary["Emails"][] = makeSetting("default_from", "text", "Default From Address");
$ary["Emails"][] = makeSetting("warning_minutes", "number", "Number of Minutes Before An Email to Send a Warning Email", Application::getWarningEmailMinutes($pid));
Expand Down Expand Up @@ -474,7 +472,35 @@ function makeSystemSetting($var, $type, $label, $default = "", $fieldChoices = [
if ($value === "") {
$value = $default;
}
return constructSetting($value, $var, $type, $label, $default, $fieldChoices, $readonly);
return constructSetting($value, $var, $type, $label, $default, $fieldChoices, $readonly, "", "");
}

function makeOptionalSetting($var, $type, $message, $numSettings) {
$divPrefix = "div_";
$i = 1;
$baseField = preg_replace("/_\d+$/", "", $var);
if (preg_match("/_(\d+)$/", $var, $matches)) {
$i = (int) $matches[1];
}
if ($i < $numSettings) {
$nextField = REDCapManagement::getOptionalFieldSetting($baseField, $i + 1);
} else {
$nextField = "";
}
if ($i == 1) {
$lastValue = FALSE;
} else {
$lastI = $i - 1;
$lastField = REDCapManagement::getOptionalFieldSetting($baseField, $lastI);
$lastValue = Application::getSetting($lastField);
}
$value = Application::getSetting($var);
$trAttributes = "id='$divPrefix$var'";
if (($i > 1) && !$value && !$lastValue) {
$trAttributes = "id='$divPrefix$var' style='display: none;'";
}
$js = $nextField ? "if ($(this).val() || $('#$divPrefix$nextField').val()) { $('#$divPrefix$nextField').show(); } else { $('#$divPrefix$nextField').hide(); }" : "";
return constructSetting($value, $var, $type, $message, "", [], FALSE, $js, $trAttributes);
}

function makeSetting($var, $type, $label, $default = "", $fieldChoices = [], $readonly = FALSE)
Expand All @@ -483,10 +509,13 @@ function makeSetting($var, $type, $label, $default = "", $fieldChoices = [], $re
if ($value === "") {
$value = $default;
}
return constructSetting($value, $var, $type, $label, $default, $fieldChoices, $readonly);
return constructSetting($value, $var, $type, $label, $default, $fieldChoices, $readonly, "", "");
}

function constructSetting($value, $var, $type, $label, $default, $fieldChoices, $readonly) {
function constructSetting($value, $var, $type, $label, $default, $fieldChoices, $readonly, $js, $trAttributes) {
# only one of these is used
$onblur = $js ? " onblur=\"$js\" " : "";
$onchange = $js ? " onchange=\"$js\" " : "";
if (in_array($var, ["event_id", "pid", "token"])) {
$module = Application::getModule();
$realValue = "";
Expand Down Expand Up @@ -521,7 +550,7 @@ function constructSetting($value, $var, $type, $label, $default, $fieldChoices,
$spacing .= "&nbsp;";
}
if (($type == "text") || ($type == "number")) {
$html .= "<tr>";
$html .= "<tr $trAttributes>";
$html .= "<td style='text-align: right;'>";
$html .= $label;
if ($default) {
Expand All @@ -531,7 +560,7 @@ function constructSetting($value, $var, $type, $label, $default, $fieldChoices,
}
}
$html .= "</td><td style='text-align: left;'>";
$html .= "<input type='$type' name='$var' value=\"$value\"";
$html .= "<input type='$type' name='$var' value=\"$value\" $onblur";
if ($readonly) {
$html .= " readonly";
}
Expand All @@ -542,7 +571,7 @@ function constructSetting($value, $var, $type, $label, $default, $fieldChoices,
if ($type == "yesno") {
$fieldChoices = ["0" => "No", "1" => "Yes"];
}
$html .= "<tr>";
$html .= "<tr $trAttributes>";
$html .= "<td style='text-align: right;'>";
$html .= $label;
$html .= "</td><td style='text-align: left;'>";
Expand All @@ -553,23 +582,23 @@ function constructSetting($value, $var, $type, $label, $default, $fieldChoices,
} else {
$selected = "";
}
$html .= "<div><input type='radio' name='$var' id='$var"."___$idx' value='$idx'$selected><label for='$var"."___$idx'> $fieldLabel</label></div>";
$html .= "<div><input type='radio' name='$var' id='$var"."___$idx' value='$idx'$selected$onchange /><label for='$var"."___$idx'> $fieldLabel</label></div>";
}
$html .= implode($spacing, $options);
$html .= "</td>";
$html .= "</tr>";
} else if (in_array($type, ["textarea", "short_textarea"])) {
$html .= "<tr>";
$html .= "<tr $trAttributes>";
$html .= "<td colspan='2'>";
if (preg_match("/^<div/", $label)) {
$html .= $label;
} else {
$html .= "<div>$label</div>";
}
if ($type == "short_textarea") {
$html .= "<textarea class='config' style='height: 250px;' name='$var'>$value</textarea>";
$html .= "<textarea class='config' style='height: 250px;' name='$var' $onblur>$value</textarea>";
} else {
$html .= "<textarea class='config' name='$var'>$value</textarea>";
$html .= "<textarea class='config' name='$var' $onblur>$value</textarea>";
}
$html .= "</td>";
$html .= "</tr>";
Expand Down
7 changes: 6 additions & 1 deletion copyProject.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
use \Vanderbilt\CareerDevLibrary\REDCapManagement;
use \Vanderbilt\CareerDevLibrary\Sanitizer;
use \Vanderbilt\CareerDevLibrary\Download;
use \Vanderbilt\FlightTrackerExternalModule\CareerDev;
use \Vanderbilt\CareerDevLibrary\DataDictionaryManagement;

require_once(__DIR__."/classes/Autoload.php");

Expand Down Expand Up @@ -41,6 +41,11 @@
Application::saveSetting($key, $value, $pid);
}
}

# metadata should have been set up before this URL is called
$metadata = Download::metadataByPid($pid);
$formsAndLabels = DataDictionaryManagement::getRepeatingFormsAndLabels($metadata);
DataDictionaryManagement::setupRepeatingForms($eventId, $formsAndLabels);
echo "Project $pid successfully set up on server.";
} else {
echo "Error: Module not enabled.";
Expand Down
Loading

0 comments on commit 38b99f1

Please sign in to comment.