diff --git a/Application.php b/Application.php index e5affe31..ce8e3b2d 100644 --- a/Application.php +++ b/Application.php @@ -92,14 +92,15 @@ public static function getEmailName($record) { } public static function getCitationFields($metadata) { - $metadataFields = REDCapManagement::getFieldsFromMetadata($metadata); - $fields = ["record_id"]; - foreach (self::$citationFields as $field) { - if (in_array($field, $metadataFields)) { - $fields[] = $field; - } - } - return $fields; + return REDCapManagement::screenForFields($metadata, self::$citationFields); + } + + public static function getCustomFields($metadata) { + return REDCapManagement::screenForFields($metadata, self::$customFields); + } + + public static function getExporterFields($metadata) { + return REDCapManagement::screenForFields($metadata, CareerDev::$exporterFields); } public static function getInstitution() { @@ -431,6 +432,7 @@ public static function getIndividualKLength() { "citation_month", "citation_day", "citation_pages", + "citation_abstract", "citation_is_research", "citation_num_citations", "citation_citations_per_year", @@ -438,6 +440,18 @@ public static function getIndividualKLength() { "citation_field_citation_rate", "citation_nih_percentile", "citation_rcr", + "citation_icite_last_update", + "citation_altmetric_score", + "citation_altmetric_image", + "citation_altmetric_details_url", + "citation_altmetric_id", + "citation_altmetric_fbwalls_count", + "citation_altmetric_feeds_count", + "citation_altmetric_gplus_count", + "citation_altmetric_posts_count", + "citation_altmetric_tweeters_count", + "citation_altmetric_accounts_count", + "citation_altmetric_last_update", ); public static $customFields = array( diff --git a/CareerDev.php b/CareerDev.php index e697e8d6..7047c6b6 100644 --- a/CareerDev.php +++ b/CareerDev.php @@ -10,7 +10,7 @@ class CareerDev { public static $passedModule = NULL; public static function getVersion() { - return "2.29.0"; + return "2.30.0"; } public static function getLockFile($pid) { @@ -690,32 +690,44 @@ public static function getMenu($menuName) { return array(); } - public static $citationFields = array( - "record_id", - "citation_doi", - "citation_pmid", - "citation_include", - "citation_source", - "citation_pmcid", - "citation_authors", - "citation_title", - "citation_pub_types", - "citation_mesh_terms", - "citation_journal", - "citation_volume", - "citation_issue", - "citation_year", - "citation_month", - "citation_day", - "citation_pages", - "citation_is_research", - "citation_num_citations", - "citation_citations_per_year", - "citation_expected_per_year", - "citation_field_citation_rate", - "citation_nih_percentile", - "citation_rcr", - ); + public static $citationFields = [ + "record_id", + "citation_pmid", + "citation_include", + "citation_source", + "citation_pmcid", + "citation_authors", + "citation_title", + "citation_pub_types", + "citation_mesh_terms", + "citation_journal", + "citation_volume", + "citation_issue", + "citation_year", + "citation_month", + "citation_day", + "citation_pages", + "citation_abstract", + "citation_is_research", + "citation_num_citations", + "citation_citations_per_year", + "citation_expected_per_year", + "citation_field_citation_rate", + "citation_nih_percentile", + "citation_rcr", + "citation_icite_last_update", + "citation_altmetric_score", + "citation_altmetric_image", + "citation_altmetric_details_url", + "citation_altmetric_id", + "citation_altmetric_fbwalls_count", + "citation_altmetric_feeds_count", + "citation_altmetric_gplus_count", + "citation_altmetric_posts_count", + "citation_altmetric_tweeters_count", + "citation_altmetric_accounts_count", + "citation_altmetric_last_update", + ]; public static $smallCitationFields = array( "record_id", @@ -820,6 +832,7 @@ public static function getMenu($menuName) { "exporter_indirect_cost_amt", "exporter_total_cost", "exporter_total_cost_sub_project", + "exporter_abstract", "exporter_last_update", ); diff --git a/FlightTrackerExternalModule.php b/FlightTrackerExternalModule.php index 83c657d0..aa54b27a 100755 --- a/FlightTrackerExternalModule.php +++ b/FlightTrackerExternalModule.php @@ -21,6 +21,7 @@ require_once(dirname(__FILE__)."/classes/Download.php"); require_once(dirname(__FILE__)."/classes/NameMatcher.php"); require_once(dirname(__FILE__)."/cronLoad.php"); +require_once(APP_PATH_DOCROOT."Classes/System.php"); class FlightTrackerExternalModule extends AbstractExternalModule { @@ -397,6 +398,8 @@ private function shareDataInternally($pids) { } function cron() { + \System::increaseMaxExecTime(7200); // 2 hours + $this->setupApplication(); $pids = $this->framework->getProjectsWithModuleEnabled(); CareerDev::log($this->getName()." running for pids ".json_encode($pids)); diff --git a/bulkImport.php b/bulkImport.php index 6258d840..c048338f 100644 --- a/bulkImport.php +++ b/bulkImport.php @@ -45,6 +45,7 @@ $unmatchedLines = []; $maxInstances = []; $i = 0; + $customFields = Application::getCustomFields($metadata); foreach ($lines as $line) { $firstName = $line[0]; $lastName = $line[1]; @@ -81,6 +82,9 @@ "custom_last_update" => date("Y-m-d"), "custom_grant_complete" => "2", ]; + if (in_array("custom_costs_total", $customFields)) { + $uploadRow["custom_costs_total"] = $line[11]; + } $upload[] = $uploadRow; } else if ($title == "Positions") { list($department, $other) = findDepartment($line[8], $choices, "promotion_department"); diff --git a/charts/makeCDATable.php b/charts/makeCDATable.php index c1f59d6a..29e4647f 100755 --- a/charts/makeCDATable.php +++ b/charts/makeCDATable.php @@ -99,7 +99,7 @@ function getTimeSpan($row, $i) { $start = $row['summary_award_date_'.$i]; $end = $row['summary_award_date_'.($i + 1)]; if ($start && $end) { - return floor(REDCapManagement::datediff($start, $end, "y") * 10) / 10; + return round(REDCapManagement::datediff($start, $end, "y") * 10) / 10; } return ""; } @@ -370,14 +370,16 @@ function appendCitationLabel($num) { } } } else { - # main path - echo "$type$date$mech$budget$link"; - $ts = getTimeSpan($normativeRow, $i); - if ($ts !== "") { - echo "
$ts
years
b/w
starts
"; - } else { - echo ""; - } + if (!in_array($grant->getVariable("type"), ["Research Fellowship"])) { + # main path + echo "$type$date$mech$budget$link"; + $ts = getTimeSpan($normativeRow, $i); + if ($ts !== "") { + echo "
$ts
years
b/w
starts
"; + } else { + echo ""; + } + } } } $i++; diff --git a/classes/Crons.php b/classes/Crons.php index ffd32164..968862b2 100644 --- a/classes/Crons.php +++ b/classes/Crons.php @@ -43,26 +43,38 @@ public function addCron($file, $method, $dayOfWeek, $records = []) { if (!empty($records)) { $cronjob->setRecords($records); } - // Application::log("Has day of week $dayOfWeek and timestamp for ".date("Y-m-d", $dateTs)); + if ($this->isDebug) { + Application::log("Has day of week $dayOfWeek and timestamp for ".date("Y-m-d", $dateTs)); + } if (in_array($dayOfWeek, $possibleDays)) { # Weekday if (!isset($this->crons[$dayOfWeek])) { $this->crons[$dayOfWeek] = []; - // Application::log("Reset cron list for $dayOfWeek"); + if ($this->isDebug) { + Application::log("Reset cron list for $dayOfWeek"); + } } $this->crons[$dayOfWeek][] = $cronjob; - // Application::log("Assigned cron for $dayOfWeek"); + if ($this->isDebug) { + Application::log("Assigned cron for $dayOfWeek"); + } } else if ($dateTs) { # Y-M-D $date = date(self::getDateFormat(), $dateTs); if (!isset($this->crons[$date])) { $this->crons[$date] = []; - // Application::log("Reset cron list for $date"); + if ($this->isDebug) { + Application::log("Reset cron list for $date"); + } } $this->crons[$date][] = $cronjob; - // Application::log("Assigned cron for $date"); + if ($this->isDebug) { + Application::log("Assigned cron for $date"); + } } - // Application::log("Added cron $method: ".$this->getNumberOfCrons()." total crons now"); + if ($this->isDebug) { + Application::log("Added cron $method: ".$this->getNumberOfCrons()." total crons now"); + } } private static function getDaysOfWeek() { @@ -138,13 +150,15 @@ public function run($adminEmail = "", $tokenName = "", $additionalEmailText = "" $records = $recordsToRun; } } - Application::log("Running ".$cronjob->getTitle()); + Application::log("Running ".$cronjob->getTitle()." with ".count($records)." records"); $run[$cronjob->getTitle()] = array("text" => "Attempted", "ts" => self::getTimestamp()); try { if (!$this->token || !$this->server) { throw new \Exception("Could not pass token '".$this->token."' or server '".$this->server."' to cron job"); } - $cronjob->run($this->token, $this->server, $this->pid, $records); + if (!$this->isDebug) { + $cronjob->run($this->token, $this->server, $this->pid, $records); + } $run[$cronjob->getTitle()] = array("text" => "Succeeded", "ts" => self::getTimestamp()); } catch(\Throwable $e) { $this->handle($e, $adminEmail, $cronjob); @@ -153,6 +167,13 @@ public function run($adminEmail = "", $tokenName = "", $additionalEmailText = "" } } if (count($toRun) > 0) { + if ($this->isDebug) { + Application::log("Attempting to save current date"); + Application::saveCurrentDate("Test", $this->pid); + Application::removeCurrentDate("Test", $this->pid); + Application::log("Done attempting to save current date"); + } + $text = $tokenName." ".$this->server."

"; foreach ($run as $title => $mssgAry) { $mssg = $mssgAry['text']; @@ -168,12 +189,18 @@ public function run($adminEmail = "", $tokenName = "", $additionalEmailText = "" } if (!class_exists("\REDCap") || !method_exists("\REDCap", "email")) { throw new \Exception("Could not instantiate REDCap class!"); - } - Application::log("Sending ".Application::getProgramName()." email for pid ".$this->pid." to $adminEmail"); - \REDCap::email($adminEmail, "noreply@vumc.org", Application::getProgramName()." Cron Report", $text); + } + if (!$this->isDebug) { + Application::log("Sending ".Application::getProgramName()." email for pid ".$this->pid." to $adminEmail"); + \REDCap::email($adminEmail, "noreply@vumc.org", Application::getProgramName()." Cron Report", $text); + } } } + public function setDebug($isDebug) { + $this->isDebug = $isDebug; + } + public function handle($e, $adminEmail, $cronjob) { Application::log("Exception ".json_encode($e)); if (!class_exists("\REDCap") || !method_exists("\REDCap", "email")) { @@ -200,6 +227,7 @@ public function handle($e, $adminEmail, $cronjob) { private $sendErrorLogs; private static $lastAdminEmail; private static $lastSendErrorLogs; + private $isDebug = FALSE; } class CronJob { diff --git a/classes/Download.php b/classes/Download.php index 31579aed..68c162f3 100644 --- a/classes/Download.php +++ b/classes/Download.php @@ -180,9 +180,12 @@ public static function primaryMentors($token, $server) { return $mentors; } - public static function trainingGrants($token, $server, $fields = array(), $traineeTypes = array(5, 6, 7), $records = []) { + public static function trainingGrants($token, $server, $fields = [], $traineeTypes = [5, 6, 7], $records = [], $metadata = []) { if (empty($fields)) { - $fields = Application::$customFields; // default + if (empty($metadata)) { + $metadata = self::metadata($token, $server); + } + $fields = Application::getCustomFields($metadata); // default } if (empty($records)) { $records = self::recordIds($token, $server); @@ -203,8 +206,8 @@ public static function trainingGrants($token, $server, $fields = array(), $train return $filteredData; } - public static function appointmentsForRecord($token, $server, $record, $traineeTypes = [5, 6, 7]) { - $redcapData = self::trainingGrants($token, $server, array("record_id", "custom_role"), $traineeTypes, [$record]); + public static function appointmentsForRecord($token, $server, $record, $traineeTypes = [5, 6, 7], $metadata = []) { + $redcapData = self::trainingGrants($token, $server, array("record_id", "custom_role"), $traineeTypes, [$record], $metadata); $types = []; foreach ($redcapData as $row) { $roleType = $row['custom_role']; @@ -215,8 +218,8 @@ public static function appointmentsForRecord($token, $server, $record, $traineeT return $types; } - public static function recordsWithTrainees($token, $server, $traineeTypes = array(5, 6, 7)) { - $redcapData = self::trainingGrants($token, $server, array("record_id", "custom_role"), $traineeTypes); + public static function recordsWithTrainees($token, $server, $traineeTypes = [5, 6, 7], $metadata = []) { + $redcapData = self::trainingGrants($token, $server, array("record_id", "custom_role"), $traineeTypes, $metadata); $records = array(); foreach ($redcapData as $row) { $recordId = $row['record_id']; diff --git a/classes/Grant.php b/classes/Grant.php index fdb98d6d..dc479e4f 100644 --- a/classes/Grant.php +++ b/classes/Grant.php @@ -1287,6 +1287,11 @@ private function getCurrentType() $specs = $this->specs; $awardNo = $this->getNumber(); + if ($specs['pi_flag'] == 'N') { + if (SHOW_GRANT_DEBUG) { Application::log($awardNo.": pi_flag is N"); } + return "N/A"; + } + if (SHOW_GRANT_DEBUG) { Application::log($awardNo.": First Pass"); } if ($type = $this->lexicallyTranslate($awardNo)) { return $type; @@ -1322,8 +1327,8 @@ public static function calculateAwardType($specs, $awardNo) { return "K Equivalent"; } else if (preg_match("/^\d?[Rr]00/", $awardNo) || preg_match("/^\d?[Kk]\s*99/", $awardNo)) { return "K99/R00"; - } else if (preg_match("/^\d?[Rr]01/", $awardNo)) { - return "R01"; + } else if (preg_match("/^\d?[Rr]01/", $awardNo)) { + return "R01"; } else if (preg_match("/^\d?[Tt]\d\d/", $awardNo) || preg_match("/^\d?[Dd]43/", $awardNo)) { return "Training Grant Admin"; } else if ($specs['direct_budget'] && ($specs['direct_budget'] >= 750000)) { @@ -1368,6 +1373,10 @@ public static function calculateAwardType($specs, $awardNo) { return "R01 Equivalent"; } else if (preg_match("/^\d?R35/", $awardNo)) { return "R01 Equivalent"; + } else if (preg_match("/^\d?[Dd][Pp]1/", $awardNo)) { + return "R01 Equivalent"; + } else if (preg_match("/^\d?DP7/", $awardNo) || preg_match("/^\d?[Rr]25/", $awardNo) || preg_match("/^\d?[Tt]90/", $awardNo)) { + return "Training Grant Admin"; } else if (preg_match("/Internal K/", $awardNo)) { return "Internal K"; } else if (preg_match("/K12\/KL2/", $awardNo)) { diff --git a/classes/GrantFactory.php b/classes/GrantFactory.php index 46c75e2a..3d1e40fd 100644 --- a/classes/GrantFactory.php +++ b/classes/GrantFactory.php @@ -713,36 +713,50 @@ class CustomGrantFactory extends GrantFactory { public function processRow($row, $token = "") { list($pid, $event_id) = self::getProjectIdentifiers($token); $awardNo = self::cleanAwardNo($row['custom_number']); + $directCosts = $row['custom_costs']; + if ($row['custom_costs_total']) { + $totalCosts = $row['custom_costs_total']; + if (!$directCosts) { + $directCosts = Grants::directCostsFromTotal($totalCosts, $awardNo, $row['custom_start']); + } + } else { + if ($directCosts) { + $totalCosts = Grants::totalCostsFromDirect($directCosts, $awardNo, $row['custom_start']); + } else { + $totalCosts = ''; + } + } $grant = new Grant($this->lexicalTranslator); $grant->setVariable('start', $row['custom_start']); $grant->setVariable('end', $row['custom_end']); $grant->setVariable('title', $row['custom_title']); - $grant->setVariable('budget', Grants::totalCostsFromDirect($row['custom_costs'], $awardNo, $row['custom_start'])); + $grant->setVariable('budget', $totalCosts); // $grant->setVariable('fAndA', Grants::getFAndA($awardNo, $row['custom_start'])); $grant->setVariable('finance_type', Grants::getFinanceType($awardNo)); - $grant->setVariable('direct_budget', $row['custom_costs']); + $grant->setVariable('direct_budget', $directCosts); $grant->setVariable('sponsor', $row['custom_org']); $grant->setVariable('original_award_number', $row['custom_number']); $grant->setNumber($awardNo); $grant->setVariable('source', "custom"); if (($row['custom_role'] == 1) || ($row['custom_role'] == 2) || ($row['custom_role'] == '')) { $grant->setVariable('pi_flag', 'Y'); + $type = $row['custom_type']; + $reverseAwardTypes = Grant::getReverseAwardTypes(); + if ($reverseAwardTypes[$type]) { + $grant->setVariable("type", $reverseAwardTypes[$type]); + } else { + $grant->putInBins(); + } } else { $grant->setVariable('pi_flag', 'N'); + $grant->putInBins(); } $grant->setVariable("role", $this->choices["custom_role"][$row["custom_role"]]); $grant->setVariable('nih_mechanism', Grant::getActivityCode($awardNo)); $grant->setVariable('link', Links::makeLink(APP_PATH_WEBROOT."DataEntry/index.php?pid=$pid&id={$row['record_id']}&event_id=$event_id&page=custom_grant&instance={$row['redcap_repeat_instance']}", "See Grant")); $grant->setVariable('last_update', $row['custom_last_update']); - $type = $row['custom_type']; - $reverseAwardTypes = Grant::getReverseAwardTypes(); - if ($reverseAwardTypes[$type]) { - $grant->setVariable("type", $reverseAwardTypes[$type]); - } else { - $grant->putInBins(); - } array_push($this->grants, $grant); } } diff --git a/classes/NIHTables.php b/classes/NIHTables.php index 13c23a8f..6eb685f8 100644 --- a/classes/NIHTables.php +++ b/classes/NIHTables.php @@ -373,7 +373,7 @@ private function get6IIData($table, $yearspan, $records = []) { $doctorateInstitutions = Download::doctorateInstitutions($this->token, $this->server, $this->metadata); $trainingTypes = self::getTrainingTypes($table); if (!empty($names)) { - $trainingGrantData = Download::trainingGrants($this->token, $this->server, array(), $trainingTypes); + $trainingGrantData = Download::trainingGrants($this->token, $this->server, [], $trainingTypes, [], $this->metadata); } else { $trainingGrantData = array(); } @@ -1311,7 +1311,7 @@ public function get8Data($table, $records = []) { $firstNames = Download::firstnames($this->token, $this->server); $lastNames = Download::lastnames($this->token, $this->server); $mentors = Download::primaryMentors($this->token, $this->server); - $trainingGrants = Download::trainingGrants($this->token, $this->server); + $trainingGrants = Download::trainingGrants($this->token, $this->server, [], [5, 6, 7], [], $this->metadata); $hasSupportSummary = $this->hasSupportSummary(); if ($hasSupportSummary) { $supportSummaries = Download::oneField($this->token, $this->server, "identifier_support_summary"); @@ -1721,7 +1721,7 @@ private function downloadRelevantNames($table, $records) { $thisGrantType = self::getTrainingType(); $internalKType = 1; if (in_array($part, [1, 3])) { - $trainingData = Download::trainingGrants($this->token, $this->server); + $trainingData = Download::trainingGrants($this->token, $this->server, [], [5, 6, 7], [], $this->metadata); foreach ($names as $recordId => $name) { $currentGrants = self::getTrainingGrantsForRecord($trainingData, $recordId); foreach ($currentGrants as $row) { @@ -1831,7 +1831,7 @@ public function get5Data($table, $records = []) { $lastNames = Download::lastNames($this->token, $this->server); $firstNames = Download::firstNames($this->token, $this->server); $mentors = Download::primaryMentors($this->token, $this->server); - $trainingData = Download::trainingGrants($this->token, $this->server); + $trainingData = Download::trainingGrants($this->token, $this->server, [], [5, 6, 7], [], $this->metadata); $trainingStarts = Download::oneField($this->token, $this->server, "summary_training_start"); } $fields = array_unique(array_merge(Application::getCitationFields($this->metadata), array("record_id"))); diff --git a/classes/Publications.php b/classes/Publications.php index 16e96a77..7f82db6f 100644 --- a/classes/Publications.php +++ b/classes/Publications.php @@ -493,10 +493,12 @@ public static function uploadBlankPMCsAndPMIDs($token, $server, $recordId, $meta } public static function getCitationsFromPubMed($pmids, $metadata, $src = "", $recordId = 0, $startInstance = 1, $confirmedPMIDs = array(), $pid = NULL) { - $upload = array(); + $metadataFields = REDCapManagement::getFieldsFromMetadata($metadata); + $hasAbstract = in_array("citation_abstract", $metadataFields); + + $upload = []; $instance = $startInstance; $pullSize = self::getPMIDLimit(); - $metadataFields = REDCapManagement::getFieldsFromMetadata($metadata); for ($i = 0; $i < count($pmids); $i += $pullSize) { $pmidsToPull = array(); for ($j = $i; ($j < count($pmids)) && ($j < $i + $pullSize); $j++) { @@ -519,7 +521,11 @@ public static function getCitationsFromPubMed($pmids, $metadata, $src = "", $rec $pmidsPulled = []; foreach ($xml->PubmedArticle as $medlineCitation) { $article = $medlineCitation->MedlineCitation->Article; - $authors = array(); + $abstract = ""; + if ($article->Abstract && $article->Abstract->AbstractText) { + $abstract = strval($article->Abstract->AbstractText); + } + $authors = []; if ($article->AuthorList->Author) { foreach ($article->AuthorList->Author as $authorXML) { $author = $authorXML->LastName . " " . $authorXML->Initials; @@ -632,6 +638,10 @@ public static function getCitationsFromPubMed($pmids, $metadata, $src = "", $rec "citation_icite_last_update" => date("Y-m-d"), "citation_complete" => "2", ]; + if ($hasAbstract) { + $row['citation_abstract'] = $abstract; + } + $altmetricRow = self::getAltmetricRow($iCite->getVariable($pmid, "doi"), $metadataFields); $row = array_merge($row, $altmetricRow); if (in_array($pmid, $confirmedPMIDs)) { @@ -1260,10 +1270,10 @@ public function getVariable($var) { private function autoSuggestCategoryAndScore() { $pubAry = $this->toArray(); if (is_array($pubAry['Publication Types']) && !empty($pubAry['Publication Types'])) { - $cat = Citation::suggestCategoryFromPubTypes($pubAry['Publication Types'], $pubAry['Title']); - if ($cat) { - return array($cat, 100); - } + // $cat = Citation::suggestCategoryFromPubTypes($pubAry['Publication Types'], $pubAry['Title']); + // if ($cat) { + // return array($cat, 100); + // } } if (isset($pubAry['Abstract'])) { return self::analyzeAbstractAndTitle($pubAry['Abstract'], $pubAry['Title']); diff --git a/classes/REDCapManagement.php b/classes/REDCapManagement.php index e84cbbe0..2d972c6d 100644 --- a/classes/REDCapManagement.php +++ b/classes/REDCapManagement.php @@ -1264,6 +1264,17 @@ public static function splitURL($fullURL) { return [$url, $params]; } + public static function screenForFields($metadata, $possibleFields) { + $metadataFields = REDCapManagement::getFieldsFromMetadata($metadata); + $fields = ["record_id"]; + foreach ($possibleFields as $field) { + if (in_array($field, $metadataFields)) { + $fields[] = $field; + } + } + return $fields; + } + public static function dedup1DArray($ary) { $newAry = []; foreach ($ary as $item) { diff --git a/classes/Upload.php b/classes/Upload.php index a5ff6d12..ce42f445 100644 --- a/classes/Upload.php +++ b/classes/Upload.php @@ -64,6 +64,16 @@ public static function deleteField($token, $server, $pid, $field, $recordId, $in } } + public static function copyRecord($token, $server, $oldRecordId, $newRecordId) { + $oldRecordData = Download::records($token, $server, [$oldRecordId]); + $newRecordData = []; + foreach ($oldRecordData as $row) { + $row['record_id'] = $newRecordId; + $newRecordData[] = $row; + } + return self::rows($newRecordData, $token, $server); + } + public static function deleteForm($token, $server, $pid, $prefix, $recordId, $instance = NULL) { $records = Download::recordIds($token, $server); if (Download::isCurrentServer($server)) { diff --git a/classes/WebOfScience.php b/classes/WebOfScience.php index 1be09e31..7a15035c 100644 --- a/classes/WebOfScience.php +++ b/classes/WebOfScience.php @@ -37,45 +37,49 @@ public function getData($pmids) { $data = []; foreach ($batchedPmids as $pmids) { - Application::log("Downloading for ".count($pmids)." PMIDs"); - $xml = $this->makeXML($pmids); - // Application::log("Uploading ".$xml); - $url = 'https://ws.isiknowledge.com/cps/xrpc'; + if (empty($pmids)) { + Application::log("No PMIDs"); + } else { + Application::log("Downloading for ".count($pmids)." PMIDs"); + $xml = $this->makeXML($pmids); + // Application::log("Uploading ".$xml); + $url = 'https://ws.isiknowledge.com/cps/xrpc'; - $curl = curl_init($url); - curl_setopt($curl, CURLOPT_HTTPHEADER, array("Content-Type: text/xml")); - curl_setopt($curl, CURLOPT_POST, true); - curl_setopt($curl, CURLOPT_POSTFIELDS, $xml); - curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); - $result = curl_exec($curl); - if (curl_errno($curl)) { - throw new Exception(curl_error($curl)); - } - curl_close($curl); - Application::log("Got ".strlen($result)." bytes from ".$url); - // Application::log($result); + $curl = curl_init($url); + curl_setopt($curl, CURLOPT_HTTPHEADER, array("Content-Type: text/xml")); + curl_setopt($curl, CURLOPT_POST, true); + curl_setopt($curl, CURLOPT_POSTFIELDS, $xml); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); + $result = curl_exec($curl); + if (curl_errno($curl)) { + throw new Exception(curl_error($curl)); + } + curl_close($curl); + Application::log("Got ".strlen($result)." bytes from ".$url); + // Application::log($result); - $maxTries = 5; - $tryNum = 0; - $done = FALSE; - while (($tryNum < $maxTries) && !$done) { - $tryNum++; - try { - $values = $this->parseXML($result); - Application::log("On try $tryNum, got ".count($values)." values from XML"); - $done = TRUE; - } catch (\Exception $e) { - Application::log("parseXML try $tryNum: ".$e->getMessage()); - sleep(120); // "wait a couple of minutes in case of error" + $maxTries = 5; + $tryNum = 0; + $done = FALSE; + while (($tryNum < $maxTries) && !$done) { + $tryNum++; + try { + $values = $this->parseXML($result); + Application::log("On try $tryNum, got ".count($values)." values from XML"); + $done = TRUE; + } catch (\Exception $e) { + Application::log("parseXML try $tryNum: ".$e->getMessage()); + sleep(120); // "wait a couple of minutes in case of error" + } } + if ($tryNum > $maxTries) { + throw new \Exception("Exceeded maximum of $maxTries tries"); + } + foreach ($values as $key => $value) { + $data[$key] = $value; + } + sleep(1); // rate-limiter } - if ($tryNum > $maxTries) { - throw new \Exception("Exceeded maximum of $maxTries tries"); - } - foreach ($values as $key => $value) { - $data[$key] = $value; - } - sleep(1); // rate-limiter } return $data; } else { diff --git a/clean/remap.php b/clean/remap.php new file mode 100644 index 00000000..83480405 --- /dev/null +++ b/clean/remap.php @@ -0,0 +1,109 @@ + $tmpRecordId) { + $tmpRecordId *= 10; +} + +if ($_POST) { + $toDelete = []; + $toChange = []; + foreach ($_POST as $key => $value) { + if (preg_match("/^record_\d+$/", $key) && $value) { + $oldRecordId = preg_replace("/^record_/", "", $key); + $newRecordId = $value; + if ($oldRecordId != $newRecordId) { + $newTmpRecordId = $tmpRecordId + $newRecordId; + Upload::copyRecord($token, $server, $oldRecordId, $newTmpRecordId); + $toDelete[] = $oldRecordId; + $toChange[$newTmpRecordId] = $newRecordId; + } + } + } + if (empty($toDelete) && empty($toChange)) { + echo "

No records requested to change.

"; + } else { + $records = Download::recordIds($token, $server); + $numAffected = count($toChange); + foreach ($toDelete as $recordId) { + Upload::deleteRecords($token, $server, [$recordId]); + } + foreach ($toChange as $oldRecordId => $newRecordId) { + if (in_array($newRecordId, $records)) { + Upload::deleteRecords($token, $server, [$newRecordId]); + } + Upload::copyRecord($token, $server, $oldRecordId, $newRecordId); + Upload::deleteRecords($token, $server, [$oldRecordId]); + } + echo "

$numAffected records affected.

"; + } +} else { + $names = Download::names($token, $server); + $link = Application::link("clean/remap.php"); + echo "

Change Record IDs

"; + echo "

Please be patient...

"; + echo "
"; + echo ""; + echo ""; + foreach ($recordIds as $recordId) { + $id = "record_$recordId"; + echo ""; + echo ""; + echo ""; + echo ""; + } + echo "
Existing Record IDNew Record ID
Record $recordId: ".$names[$recordId]."
"; + echo ""; + echo "

"; + echo "
"; +} + diff --git a/cronLoad.php b/cronLoad.php index 2e647663..7c49402e 100644 --- a/cronLoad.php +++ b/cronLoad.php @@ -21,11 +21,11 @@ function loadCrons(&$manager, $specialOnly = FALSE, $token = "", $server = "") { // $manager->addCron("drivers/2o_updateCoeus.php", "processCoeus", date("Y-m-d")); // $manager->addCron("publications/getAllPubs_func.php", "getPubs", date("Y-m-d")); // $manager->addCron("drivers/6d_makeSummary.php", "makeSummary", date("Y-m-d")); - $manager->addCron("publications/updateBibliometricsForOneRecord.php", "updateBibliometrics", date("Y-m-d")); + $manager->addCron("drivers/2m_updateExPORTER.php", "updateExPORTER", date("Y-m-d")); } else if ($token && $server) { $has = checkMetadataForFields($token, $server); - $manager->addCron("drivers/2m_updateExPORTER.php", "updateExPORTER", "Monday"); + $manager->addCron("drivers/2m_updateExPORTER.php", "updateExPORTER", "Monday"); $manager->addCron("drivers/2n_updateReporters.php", "updateReporter", "Tuesday"); if ($has['coeus']) { $manager->addCron("drivers/2o_updateCoeus.php", "processCoeus", "Thursday"); @@ -43,16 +43,12 @@ function loadCrons(&$manager, $specialOnly = FALSE, $token = "", $server = "") { } } $manager->addCron("drivers/13_pullOrcid.php", "pullORCIDs", "Friday"); - $manager->addCron("publications/getAllPubs_func.php", "getPubs", "Saturday"); + $manager->addCron("publications/getAllPubs_func.php", "getPubs", "Saturday"); # limited group because bibliometric updates take a lot of time due to rate limiters $bibliometricRecordsToUpdate = getRecordsToUpdateBibliometrics($token, $server, date("d"), date("t")); if (!empty($bibliometricRecordsToUpdate)) { - if ((Application::getPid($token) == "112169") && CareerDev::isVanderbilt() && (date("Y-m-d") == "2021-01-23")) { - $manager->addCron("publications/updateBibliometrics.php", "updateBibliometrics", date("Y-m-d")); - } else { - $manager->addCron("publications/updateBibliometrics.php", "updateBibliometrics", date("Y-m-d"), $bibliometricRecordsToUpdate); - } + $manager->addCron("publications/updateBibliometrics.php", "updateBibliometrics", date("Y-m-d"), $bibliometricRecordsToUpdate); } $manager->addCron("drivers/6d_makeSummary.php", "makeSummary", "Monday"); $manager->addCron("drivers/6d_makeSummary.php", "makeSummary", "Tuesday"); diff --git a/customGrants.php b/customGrants.php index 188dd542..ef501cc4 100644 --- a/customGrants.php +++ b/customGrants.php @@ -2,18 +2,21 @@ use \Vanderbilt\CareerDevLibrary\Links; use \Vanderbilt\CareerDevLibrary\Download; +use \Vanderbilt\CareerDevLibrary\Application; use \Vanderbilt\FlightTrackerExternalModule\CareerDev; require_once(dirname(__FILE__)."/charts/baseWeb.php"); require_once(dirname(__FILE__)."/classes/Links.php"); require_once(dirname(__FILE__)."/classes/Download.php"); require_once(dirname(__FILE__)."/CareerDev.php"); +require_once(dirname(__FILE__)."/Application.php"); if ($_GET['record']) { $record = $_GET['record']; $pid = $_GET['pid']; - $redcapData = Download::fieldsForRecords($token, $server, CareerDev::$customFields, array($record)); + $metadata = Download::metadata($token, $server); + $redcapData = Download::fieldsForRecords($token, $server, Application::getCustomFields($metadata), [$record]); $max = 0; foreach ($redcapData as $row) { if (($row['redcap_repeat_instrument'] == "custom_grant") && ($row['redcap_repeat_instance'] > $max)) { diff --git a/drivers/2m_updateExPORTER.php b/drivers/2m_updateExPORTER.php index d64e969e..b6b3aeb3 100644 --- a/drivers/2m_updateExPORTER.php +++ b/drivers/2m_updateExPORTER.php @@ -3,14 +3,18 @@ use \Vanderbilt\CareerDevLibrary\Download; use \Vanderbilt\CareerDevLibrary\Upload; use \Vanderbilt\CareerDevLibrary\NameMatcher; +use \Vanderbilt\CareerDevLibrary\Application; +use \Vanderbilt\CareerDevLibrary\REDCapManagement; use \Vanderbilt\FlightTrackerExternalModule\CareerDev; define('NOAUTH', true); require_once(dirname(__FILE__)."/../small_base.php"); require_once(dirname(__FILE__)."/../CareerDev.php"); +require_once(dirname(__FILE__)."/../Application.php"); require_once(dirname(__FILE__)."/../classes/Download.php"); require_once(dirname(__FILE__)."/../classes/NameMatcher.php"); require_once(dirname(__FILE__)."/../classes/Upload.php"); +require_once(dirname(__FILE__)."/../classes/REDCapManagement.php"); require_once(dirname(__FILE__)."/../../../redcap_connect.php"); /** @@ -108,25 +112,70 @@ function downloadURLAndUnzip($file) { * @param $headers array read from CSV that consist of the headers for each row * constraint: count($line) == count($headers) */ -function makeUploadHoldingQueue($line, $headers) { +function makeUploadHoldingQueue($line, $headers, $abstracts) { $j = 0; $dates = array("exporter_budget_start", "exporter_budget_end", "exporter_project_start", "exporter_project_end"); $uploadLineHoldingQueue = array(); foreach ($line as $item) { $field = "exporter_".strtolower($headers[$j]); if (in_array($field, $dates)) { - $item = \Vanderbilt\FlightTrackerExternalModule\MDY2YMD($item); + $item = REDCapManagement::MDY2YMD($item); } $uploadLineHoldingQueue[$field] = convert_from_latin1_to_utf8_recursively($item); $j++; } - $uploadLineHoldingQueue['exporter_last_update'] = date("Y-m-d"); + if ($uploadLineHoldingQueue['exporter_application_id']) { + $uploadLineHoldingQueue['exporter_abstract'] = $abstracts[$uploadLineHoldingQueue['exporter_application_id']]; + } + $uploadLineHoldingQueue['exporter_last_update'] = date("Y-m-d"); $uploadLineHoldingQueue['exporter_complete'] = '2'; return $uploadLineHoldingQueue; } +function updateAbstracts($token, $server, $pid) { + $records = Download::recordIds($token, $server); + $files = []; + $abstractFiles = []; + + # find relevant zips + # download relevent zips into APP_PATH_TEMP + # unzip zip files + for ($year = 2009; $year <= date("Y"); $year++) { + $url = "RePORTER_PRJ_C_FY".$year.".zip"; + $file = downloadURLAndUnzip($url); + if ($file) { + $files[$file] = $year; + } + + $abstractURL = "RePORTER_PRJABS_C_FY".$year.".zip"; + $abstractFile = downloadURLAndUnzip($abstractURL); + if ($abstractFile) { + $abstractFiles[$file] = $abstractFile; + } + } + for ($year = date("Y") - 1; $year <= date("Y") + 1; $year++) { + for ($week = 1; $week <= 53; $week++) { + $weekWithLeading0s = sprintf('%03d', $week); + $url = "RePORTER_PRJ_C_FY".$year."_".$weekWithLeading0s.".zip"; + $file = downloadURLAndUnzip($url); + if ($file) { + $files[$file] = $year; + } + + $abstractURL = "RePORTER_PRJABS_C_FY".$year."_".$weekWithLeading0s.".zip"; + $abstractFile = downloadURLAndUnzip($abstractURL); + if ($abstractFile) { + $abstractFiles[$file] = $abstractFile; + } + } + } + + uploadBlankAbstracts($token, $server, $records, $abstractFiles); +} + function updateExPORTER($token, $server, $pid, $records) { - $files = array(); + $files = []; + $abstractFiles = []; # find relevant zips # download relevent zips into APP_PATH_TEMP @@ -137,6 +186,12 @@ function updateExPORTER($token, $server, $pid, $records) { if ($file) { $files[$file] = $year; } + + $abstractURL = "RePORTER_PRJABS_C_FY".$year.".zip"; + $abstractFile = downloadURLAndUnzip($abstractURL); + if ($abstractFile) { + $abstractFiles[$file] = $abstractFile; + } } for ($year = date("Y") - 1; $year <= date("Y") + 1; $year++) { for ($week = 1; $week <= 53; $week++) { @@ -146,16 +201,25 @@ function updateExPORTER($token, $server, $pid, $records) { if ($file) { $files[$file] = $year; } + + $abstractURL = "RePORTER_PRJABS_C_FY".$year."_".$weekWithLeading0s.".zip"; + $abstractFile = downloadURLAndUnzip($abstractURL); + if ($abstractFile) { + $abstractFiles[$file] = $abstractFile; + } } } - CareerDev::log("Downloading REDCap"); echo "Downloading REDCap\n"; + $metadata = Download::metadata($token, $server); + $metadataFields = REDCapManagement::getFieldsFromMetadata($metadata); + $hasAbstract = in_array("exporter_abstract", $metadataFields); + $redcapData = array(); foreach ($records as $recordId) { - $redcapData[$recordId] = Download::fieldsForRecords($token, $server, array_unique(array_merge(CareerDev::$customFields, CareerDev::$exporterFields)), array($recordId)); + $redcapData[$recordId] = Download::fieldsForRecords($token, $server, array_unique(array_merge(Application::getCustomFields($metadata), Application::getExporterFields($metadata))), array($recordId)); } echo "Downloaded ".count($redcapData)." records\n"; @@ -175,6 +239,8 @@ function updateExPORTER($token, $server, $pid, $records) { $upload = array(); $newUploads = array(); // new records foreach ($files as $file => $year) { + $abstracts = readAbstracts($abstractFiles[$file]); + CareerDev::log("Reading $file"); echo "Reading $file\n"; $fp = fopen($file, "r"); @@ -243,14 +309,27 @@ function updateExPORTER($token, $server, $pid, $records) { if ($recordId && $firstNames[$k] && $lastNames[$k]) { # upload line $uploadLine = array("record_id" => $recordId, "redcap_repeat_instrument" => "exporter", "exporter_complete" => '2'); - $uploadLineHoldingQueue = makeUploadHoldingQueue($line, $headers); + $uploadLineHoldingQueue = makeUploadHoldingQueue($line, $headers, $abstracts); list($uploadLine["redcap_repeat_instance"], $isNew) = getExPORTERInstance($recordId, $redcapData[$recordId], $upload, $uploadLineHoldingQueue); if ($isNew) { $uploadLine = array_merge($uploadLine, $uploadLineHoldingQueue); CareerDev::log("Matched name {$recordId} {$firstNames[$k]} {$lastNames[$k]} = {$uploadLine['exporter_pi_names']}"); echo "Matched name {$recordId} {$firstNames[$k]} {$lastNames[$k]} = {$uploadLine['exporter_pi_names']}\n"; + if ($hasAbstract && $uploadLine['exporter_application_id']) { + $uploadLine['exporter_abstract'] = $abstracts[$uploadLine['exporter_application_id']]; + } $upload[] = $uploadLine; - } + } else { + $currRow = REDCapManagement::getRow($redcapData[$recordId], $recordId, "exporter", $uploadLine['redcap_repeat_instance']); + if (!$currRow['exporter_abstract'] && $currRow['export_application_id'] && $hasAbstract) { + $upload[] = [ + "record_id" => $recordId, + "redcap_repeat_instrument" => "exporter", + "redcap_repeat_instance" => $uploadLine["redcap_repeat_instance"], + "exporter_abstract" => $abstracts[$uploadLine['exporter_application_id']], + ]; + } + } } else if (!$recordId && $firstNames[$k] && $lastNames[$k] && $year >= date("Y")) { # new person? $j = 0; @@ -271,7 +350,7 @@ function updateExPORTER($token, $server, $pid, $records) { $j++; } if ($isK && $isSupportYear1) { - $uploadLineHoldingQueue = makeUploadHoldingQueue($line, $headers); + $uploadLineHoldingQueue = makeUploadHoldingQueue($line, $headers, $abstracts); $newUploads[$firstNames[$k]." ".$lastNames[$k]] = $uploadLineHoldingQueue; } } @@ -304,6 +383,9 @@ function updateExPORTER($token, $server, $pid, $records) { list($firstName, $lastName) = preg_split("/\s/", $fullName); $upload[] = array("record_id" => $maxRecordId, "redcap_repeat_instrument" => "", "redcap_repeat_instance" => "", "identifier_first_name" => ucfirst(strtolower($firstName)), "identifier_last_name" => ucfirst(strtolower($lastName))); + if ($hasAbstract && $uploadLine['exporter_application_id']) { + $uploadLine['exporter_abstract'] = $abstracts[$uploadLine['exporter_application_id']]; + } $upload[] = $uploadLine; } @@ -315,8 +397,70 @@ function updateExPORTER($token, $server, $pid, $records) { echo json_encode($feedback)."\n"; } + if ($hasAbstract) { + uploadBlankAbstracts($token, $server, $records, $abstractFiles); + } + // $mssg = "NIH Exporter run\n\n".count($upload)." rows\n".$output."\n\n"; // \REDCap::email($adminEmail, "no-reply@vanderbilt.edu", "CareerDev NIH Exporter", $mssg); CareerDev::saveCurrentDate("Last NIH ExPORTER Download", $pid); } + +function readAbstracts($file) { + $data = []; + if (file_exists($file)) { + $fp = fopen($file, "r"); + $headers = fgetcsv($fp); + while ($line = fgetcsv($fp)) { + $appId = $line[0]; + $abstract = $line[1]; + if ($appId && $abstract) { + $data[$appId] = $abstract; + } + } + fclose($fp); + } + return $data; +} + +function uploadBlankAbstracts($token, $server, $records, $abstractFiles) { + foreach ($records as $recordId) { + $fields = ["record_id", "exporter_application_id", "exporter_abstract"]; + $redcapData = Download::fieldsForRecords($token, $server, $fields, [$recordId]); + $blankApplicationIds = []; + foreach ($redcapData as $row) { + if ($row['redcap_repeat_instrument'] == "exporter") { + if ($row['exporter_abstract'] == "") { + $blankApplicationIds[$row['redcap_repeat_instance']] = $row['exporter_application_id']; + } + } + } + + $upload = []; + foreach ($blankApplicationIds as $instance => $applicationId) { + $found = FALSE; + foreach ($abstractFiles as $dataFile => $abstractFile) { + $fp = fopen($abstractFile, "r"); + while (!$found && ($line = fgetcsv($fp))) { + if ($line[1] && ($line[0] == $applicationId)) { + $upload[] = [ + "record_id" => $recordId, + "redcap_repeat_instrument" => "exporter", + "redcap_repeat_instance" => $instance, + "exporter_abstract" => $line[1], + ]; + $found = TRUE; + } + } + fclose($fp); + if ($found) { + break; // inner + } + } + } + if (!empty($upload)) { + Upload::rows($upload, $token, $server); + } + } +} diff --git a/emailMgmt/viewQueue.php b/emailMgmt/viewQueue.php new file mode 100644 index 00000000..ddfc8a93 --- /dev/null +++ b/emailMgmt/viewQueue.php @@ -0,0 +1,45 @@ +getQueue($startTs); + +echo "

Email Queue

"; +echo "

Current Date and Time: ".date("m-d-Y H:i", $startTs)."

"; + +if (empty($queue)) { + echo "

No emails are presently enqueued.

"; +} else { + echo "

Pending Emails

"; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + $rowNum = 0; + foreach ($queue as $row) { + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + $rowNum++; + } + echo "
Email NameDate/Time to SendFromSubjectTo
".$row['name']."".REDCapManagement::YMD2MDY($row['date'])." ".$row['time']."".$row['from']."".$row['subject']."".$row['to_count']." recipients
".implode("
", $row['to'])."
"; +} diff --git a/getAbstracts.php b/getAbstracts.php new file mode 100644 index 00000000..33af58d3 --- /dev/null +++ b/getAbstracts.php @@ -0,0 +1,56 @@ + $row) { + fputcsv($fp, $row); +} +fclose($fp); \ No newline at end of file diff --git a/help/Codebook.docx b/help/Codebook.docx index db2f5b0a..9f7782bb 100644 Binary files a/help/Codebook.docx and b/help/Codebook.docx differ diff --git a/help/Codebook.pdf b/help/Codebook.pdf index 17ed467f..b70315b4 100644 Binary files a/help/Codebook.pdf and b/help/Codebook.pdf differ diff --git a/img/flight_tracker_logo_medium_white_bg.png b/img/flight_tracker_logo_medium_white_bg.png new file mode 100644 index 00000000..03ab9592 Binary files /dev/null and b/img/flight_tracker_logo_medium_white_bg.png differ diff --git a/import.csv b/import.csv index 6f13109f..7921fc61 100644 --- a/import.csv +++ b/import.csv @@ -1 +1 @@ -First Name,Last Name,Grant Title,Grant Number or Funding Mechanism or Funding Mechanism (e.g. 1R01HL1234...),Grant Type (Internal K; K12/KL2; Individual K; K Equivalent; R01; R01 Equivalent; Research Fellowship; Training Grant Admin; K99/R00),Sponsoring Organization (e.g. NIH; CDC; VA),Recipient Organization (e.g. Vanderbilt),Role on Grant (PI; Co-PI; Co-I; Other; Trainee; Pre-Doctoral Trainee; Post-Doctoral Trainee),Start Date (YYYY-MM-DD or MM-DD-YYYY),End Date (YYYY-MM-DD or MM-DD-YYYY),Direct costs from start date to end date +First Name,Last Name,Grant Title,Grant Number or Funding Mechanism or Funding Mechanism (e.g. 1R01HL1234...),Grant Type (Internal K; K12/KL2; Individual K; K Equivalent; R01; R01 Equivalent; Research Fellowship; Training Grant Admin; K99/R00),Sponsoring Organization (e.g. NIH; CDC; VA),Recipient Organization (e.g. Vanderbilt),Role on Grant (PI; Co-PI; Co-I; Other; Trainee; Pre-Doctoral Trainee; Post-Doctoral Trainee),Start Date (YYYY-MM-DD or MM-DD-YYYY),End Date (YYYY-MM-DD or MM-DD-YYYY),Direct costs from start date to end date,Total costs from start date to end date diff --git a/metadata.json b/metadata.json index 8102d069..e4b78518 100644 --- a/metadata.json +++ b/metadata.json @@ -789,6 +789,7 @@ {"field_name":"custom_start","form_name":"custom_grant","section_header":"","field_type":"text","field_label":"Start Date of Funding","select_choices_or_calculations":"","field_note":"","text_validation_type_or_show_slider_number":"date_mdy","text_validation_min":"","text_validation_max":"","identifier":"","branching_logic":"","required_field":"y","custom_alignment":"","question_number":"","matrix_group_name":"","matrix_ranking":"","field_annotation":""}, {"field_name":"custom_end","form_name":"custom_grant","section_header":"","field_type":"text","field_label":"End Date of Funding","select_choices_or_calculations":"","field_note":"","text_validation_type_or_show_slider_number":"date_mdy","text_validation_min":"","text_validation_max":"","identifier":"","branching_logic":"","required_field":"","custom_alignment":"","question_number":"","matrix_group_name":"","matrix_ranking":"","field_annotation":""}, {"field_name":"custom_costs","form_name":"custom_grant","section_header":"","field_type":"text","field_label":"Direct costs from start date to end date","select_choices_or_calculations":"","field_note":"A whole number without a dollar sign and without commas","text_validation_type_or_show_slider_number":"number","text_validation_min":"","text_validation_max":"","identifier":"","branching_logic":"","required_field":"","custom_alignment":"","question_number":"","matrix_group_name":"","matrix_ranking":"","field_annotation":""}, +{"field_name":"custom_costs_total","form_name":"custom_grant","section_header":"","field_type":"text","field_label":"Total costs from start date to end date","select_choices_or_calculations":"","field_note":"A whole number without a dollar sign and without commas","text_validation_type_or_show_slider_number":"number","text_validation_min":"","text_validation_max":"","identifier":"","branching_logic":"","required_field":"","custom_alignment":"","question_number":"","matrix_group_name":"","matrix_ranking":"","field_annotation":""}, {"field_name":"custom_last_update","form_name":"custom_grant","section_header":"","field_type":"text","field_label":"Last Updated","select_choices_or_calculations":"","field_note":"","text_validation_type_or_show_slider_number":"date_ymd","text_validation_min":"","text_validation_max":"","identifier":"","branching_logic":"","required_field":"","custom_alignment":"","question_number":"","matrix_group_name":"","matrix_ranking":"","field_annotation":""}, {"field_name":"reporter_projectnumber","form_name":"reporter","section_header":"","field_type":"text","field_label":"projectNumber","select_choices_or_calculations":"","field_note":"","text_validation_type_or_show_slider_number":"","text_validation_min":"","text_validation_max":"","identifier":"","branching_logic":"","required_field":"","custom_alignment":"","question_number":"","matrix_group_name":"","matrix_ranking":"","field_annotation":""}, {"field_name":"reporter_fy","form_name":"reporter","section_header":"","field_type":"text","field_label":"fy","select_choices_or_calculations":"","field_note":"","text_validation_type_or_show_slider_number":"","text_validation_min":"","text_validation_max":"","identifier":"","branching_logic":"","required_field":"","custom_alignment":"","question_number":"","matrix_group_name":"","matrix_ranking":"","field_annotation":""}, @@ -1111,6 +1112,7 @@ {"field_name":"exporter_indirect_cost_amt","form_name":"exporter","section_header":"","field_type":"text","field_label":"Indirect Cost Amt","select_choices_or_calculations":"","field_note":"","text_validation_type_or_show_slider_number":"","text_validation_min":"","text_validation_max":"","identifier":"","branching_logic":"","required_field":"","custom_alignment":"","question_number":"","matrix_group_name":"","matrix_ranking":"","field_annotation":""}, {"field_name":"exporter_total_cost","form_name":"exporter","section_header":"","field_type":"text","field_label":"Total Cost","select_choices_or_calculations":"","field_note":"","text_validation_type_or_show_slider_number":"","text_validation_min":"","text_validation_max":"","identifier":"","branching_logic":"","required_field":"","custom_alignment":"","question_number":"","matrix_group_name":"","matrix_ranking":"","field_annotation":""}, {"field_name":"exporter_total_cost_sub_project","form_name":"exporter","section_header":"","field_type":"text","field_label":"Total Cost Sub Project","select_choices_or_calculations":"","field_note":"","text_validation_type_or_show_slider_number":"","text_validation_min":"","text_validation_max":"","identifier":"","branching_logic":"","required_field":"","custom_alignment":"","question_number":"","matrix_group_name":"","matrix_ranking":"","field_annotation":""}, +{"field_name":"exporter_abstract","form_name":"exporter","section_header":"","field_type":"notes","field_label":"Abstract","select_choices_or_calculations":"","field_note":"","text_validation_type_or_show_slider_number":"","text_validation_min":"","text_validation_max":"","identifier":"","branching_logic":"","required_field":"","custom_alignment":"","question_number":"","matrix_group_name":"","matrix_ranking":"","field_annotation":""}, {"field_name":"exporter_last_update","form_name":"exporter","section_header":"","field_type":"text","field_label":"Last Updated","select_choices_or_calculations":"","field_note":"","text_validation_type_or_show_slider_number":"","text_validation_min":"","text_validation_max":"","identifier":"","branching_logic":"","required_field":"","custom_alignment":"","question_number":"","matrix_group_name":"","matrix_ranking":"","field_annotation":""}, {"field_name":"citation_pmid","form_name":"citation","section_header":"","field_type":"text","field_label":"PubMed ID (PMID)","select_choices_or_calculations":"","field_note":"","text_validation_type_or_show_slider_number":"","text_validation_min":"","text_validation_max":"","identifier":"y","branching_logic":"","required_field":"","custom_alignment":"","question_number":"","matrix_group_name":"","matrix_ranking":"","field_annotation":""}, {"field_name":"citation_include","form_name":"citation","section_header":"","field_type":"yesno","field_label":"Include?","select_choices_or_calculations":"","field_note":"","text_validation_type_or_show_slider_number":"","text_validation_min":"","text_validation_max":"","identifier":"","branching_logic":"","required_field":"","custom_alignment":"","question_number":"","matrix_group_name":"","matrix_ranking":"","field_annotation":""}, @@ -1129,6 +1131,7 @@ {"field_name":"citation_day","form_name":"citation","section_header":"","field_type":"text","field_label":"Day","select_choices_or_calculations":"","field_note":"","text_validation_type_or_show_slider_number":"","text_validation_min":"","text_validation_max":"","identifier":"","branching_logic":"","required_field":"","custom_alignment":"","question_number":"","matrix_group_name":"","matrix_ranking":"","field_annotation":""}, {"field_name":"citation_pages","form_name":"citation","section_header":"","field_type":"text","field_label":"Pages","select_choices_or_calculations":"","field_note":"","text_validation_type_or_show_slider_number":"","text_validation_min":"","text_validation_max":"","identifier":"","branching_logic":"","required_field":"","custom_alignment":"","question_number":"","matrix_group_name":"","matrix_ranking":"","field_annotation":""}, {"field_name":"citation_grants","form_name":"citation","section_header":"","field_type":"notes","field_label":"Associated Grants","select_choices_or_calculations":"","field_note":"","text_validation_type_or_show_slider_number":"","text_validation_min":"","text_validation_max":"","identifier":"","branching_logic":"","required_field":"","custom_alignment":"","question_number":"","matrix_group_name":"","matrix_ranking":"","field_annotation":""}, +{"field_name":"citation_abstract","form_name":"citation","section_header":"","field_type":"notes","field_label":"Abstract","select_choices_or_calculations":"","field_note":"","text_validation_type_or_show_slider_number":"","text_validation_min":"","text_validation_max":"","identifier":"","branching_logic":"","required_field":"","custom_alignment":"","question_number":"","matrix_group_name":"","matrix_ranking":"","field_annotation":""}, {"field_name":"citation_is_research","form_name":"citation","section_header":"iCite terms","field_type":"yesno","field_label":"Is Research? (from iCite)","select_choices_or_calculations":"","field_note":"","text_validation_type_or_show_slider_number":"","text_validation_min":"","text_validation_max":"","identifier":"","branching_logic":"","required_field":"","custom_alignment":"","question_number":"","matrix_group_name":"","matrix_ranking":"","field_annotation":""}, {"field_name":"citation_is_research_override","form_name":"citation","section_header":"","field_type":"radio","field_label":"Override iCite's designation","select_choices_or_calculations":"1, Original Research | 2, Not Original Research","field_note":"","text_validation_type_or_show_slider_number":"","text_validation_min":"","text_validation_max":"","identifier":"","branching_logic":"","required_field":"","custom_alignment":"","question_number":"","matrix_group_name":"","matrix_ranking":"","field_annotation":""}, {"field_name":"citation_num_citations","form_name":"citation","section_header":"","field_type":"text","field_label":"Number of Citations by Other Papers (from iCite)","select_choices_or_calculations":"","field_note":"","text_validation_type_or_show_slider_number":"","text_validation_min":"","text_validation_max":"","identifier":"","branching_logic":"","required_field":"","custom_alignment":"","question_number":"","matrix_group_name":"","matrix_ranking":"","field_annotation":""}, diff --git a/publications/getAllPubs_func.php b/publications/getAllPubs_func.php index 79a133df..4f999280 100644 --- a/publications/getAllPubs_func.php +++ b/publications/getAllPubs_func.php @@ -23,9 +23,11 @@ function getPubs($token, $server, $pid, $records) { $cleanOldData = FALSE; - $metadata = Download::metadata($token, $server); + $metadata = Download::metadata($token, $server); + $metadataFields = REDCapManagement::getFieldsFromMetadata($metadata); + $hasAbstract = in_array("citation_abstract", $metadataFields); - $records = Download::recordIds($token, $server); + $records = Download::recordIds($token, $server); $citationIds = array(); $pullSize = 1; @@ -55,8 +57,22 @@ function getPubs($token, $server, $pid, $records) { if (!isset($maxInstances[$recordId]) || ($instance > $maxInstances[$recordId])) { $maxInstances[$recordId] = $instance; } + if (!$row['citation_abstract'] && $hasAbstract) { + $pubmedMatch = Publications::downloadPMID($row['citation_pmid']); + $abstract = $pubmedMatch->getVariable("Abstract"); + if ($abstract) { + $uploadRow = [ + "record_id" => $recordId, + "redcap_repeat_instrument" => "citation", + "redcap_repeat_instance" => $instance, + "citation_abstract" => $abstract, + ]; + Upload::oneRow($uploadRow, $token, $server); + } + } } } + Publications::uploadBlankPMCsAndPMIDs($token, $server, $recordId, $metadata, $redcapData); binREDCapRows($redcapData, $citationIds); } @@ -117,7 +133,7 @@ function removeDuplicates($token, $server, $rows, $recordId) { "redcap_repeat_instance" => $row['redcap_repeat_instance'], "citation_include" => "0", ); - upload(array($uploadRow), $token, $server); + upload([$uploadRow], $token, $server); } else { array_push($alreadySeen, $pmid); } diff --git a/reporting/addAppointment.php b/reporting/addAppointment.php index 91a1eebb..f0e161d7 100644 --- a/reporting/addAppointment.php +++ b/reporting/addAppointment.php @@ -22,7 +22,8 @@ die("Invalid record"); } -$redcapData = Download::fieldsForRecords($token, $server, Application::$customFields, [$recordId]); +$metadata = Download::metadata($token, $server); +$redcapData = Download::fieldsForRecords($token, $server, Application::getCustomFields($metadata), [$recordId]); $max = REDCapManagement::getMaxInstance($redcapData, "custom_grant", $recordId); if ($start && !REDCapManagement::isDate($start)) {