diff --git a/modules/api/php/endpoints/candidates.class.inc b/modules/api/php/endpoints/candidates.class.inc index 7627fbbd056..df8562dcf65 100644 --- a/modules/api/php/endpoints/candidates.class.inc +++ b/modules/api/php/endpoints/candidates.class.inc @@ -154,6 +154,10 @@ class Candidates extends Endpoint implements \LORIS\Middleware\ETagCalculator return new \LORIS\Http\Response\JSON\NotFound('Candidate not found'); } + if (!$candidate->isAccessibleBy($user)) { + return new \LORIS\Http\Response\JSON\Forbidden(); + } + $endpoint = new Candidate\Candidate($candidate); $pathparts = array_slice($pathparts, 2); diff --git a/modules/configuration/templates/form_configuration.tpl b/modules/configuration/templates/form_configuration.tpl index 07d44c118f7..a9be0374d7a 100644 --- a/modules/configuration/templates/form_configuration.tpl +++ b/modules/configuration/templates/form_configuration.tpl @@ -107,7 +107,7 @@ {elseif $node['DataType'] eq 'date_format'} {call createDateFormat k=$id v=$v d=$node['Disabled']} {elseif $node['DataType'] eq 'email'} - {call createEmail k=$id v=$id d=$node['Disabled']} + {call createEmail k=$id v=$v d=$node['Disabled']} {elseif $node['DataType'] eq 'textarea'} {call createTextArea k=$id v=$v d=$node['Disabled']} {elseif $node['DataType'] eq 'lookup_center'} diff --git a/modules/imaging_uploader/jsx/UploadForm.js b/modules/imaging_uploader/jsx/UploadForm.js index d04349a8c48..58479cc2115 100644 --- a/modules/imaging_uploader/jsx/UploadForm.js +++ b/modules/imaging_uploader/jsx/UploadForm.js @@ -66,10 +66,22 @@ class UploadForm extends Component { let ids = patientName.split('_'); formData.candID = ids[1]; formData.pSCID = ids[0]; - // visitLabel can contain underscores - // join the remaining elements of patientName and use as visitLabel + // visitLabel can contain underscores, filename can have suffix appended to PSCID_CandID_VisitLabel + // join the remaining elements of patientName and pattern match + // against each visit label. Use as visitLabel the best (longest) match ids.splice(0, 2); - formData.visitLabel = ids.join('_'); + const suffix = ids.join('_'); + const visitLabels = Object.keys(form.visitLabel.options); + let bestMatch = ''; + visitLabels.map((visitLabel) => { + if (suffix.match(visitLabel) !== null) { + // consider the first match only + if (suffix.match(visitLabel)[0].length > bestMatch.length) { + bestMatch = suffix.match(visitLabel)[0]; + } + } + }); + formData.visitLabel = bestMatch; } } @@ -81,10 +93,22 @@ class UploadForm extends Component { let ids = patientName.split('_'); formData.candID = ids[1]; formData.pSCID = ids[0]; - // visitLabel can contain underscores - // join the remaining elements of patientName and use as visitLabel + // visitLabel can contain underscores, filename can have suffix appended to PSCID_CandID_VisitLabel + // join the remaining elements of patientName and pattern match + // against each visit label. Use as visitLabel the best (longest) match ids.splice(0, 2); - formData.visitLabel = ids.join('_'); + const suffix = ids.join('_'); + const visitLabels = Object.keys(form.visitLabel.options); + let bestMatch = ''; + visitLabels.map((visitLabel) => { + if (suffix.match(visitLabel) !== null) { + // consider the first match only + if (suffix.match(visitLabel)[0].length > bestMatch.length) { + bestMatch = suffix.match(visitLabel)[0]; + } + } + }); + formData.visitLabel = bestMatch; } } diff --git a/modules/issue_tracker/php/edit.class.inc b/modules/issue_tracker/php/edit.class.inc index 73da2239e3d..24862c5642c 100644 --- a/modules/issue_tracker/php/edit.class.inc +++ b/modules/issue_tracker/php/edit.class.inc @@ -481,11 +481,11 @@ class Edit extends \NDB_Page implements ETagCalculator $historyValues = $this->getChangedValues($issueValues, $issueID, $user); if (!empty($issueID)) { - $db->update('issues', $issueValues, ['issueID' => $issueID]); + $db->unsafeUpdate('issues', $issueValues, ['issueID' => $issueID]); } else { $issueValues['reporter'] = $user->getUsername(); $issueValues['dateCreated'] = date('Y-m-d H:i:s'); - $db->insert('issues', $issueValues); + $db->unsafeInsert('issues', $issueValues); $issueID = intval($db->getLastInsertId()); } @@ -873,7 +873,7 @@ class Edit extends \NDB_Page implements ETagCalculator 'issueID' => $issueID, 'addedBy' => $user->getUsername(), ]; - $db->insert('issues_history', $changedValues); + $db->unsafeInsert('issues_history', $changedValues); } } } @@ -896,7 +896,7 @@ class Edit extends \NDB_Page implements ETagCalculator 'addedBy' => $user->getUsername(), 'issueID' => $issueID, ]; - $db->insert('issues_comments', $commentValues); + $db->unsafeInsert('issues_comments', $commentValues); } } diff --git a/modules/media/ajax/FileUpload.php b/modules/media/ajax/FileUpload.php index a91f64d00ca..5af60b691ae 100644 --- a/modules/media/ajax/FileUpload.php +++ b/modules/media/ajax/FileUpload.php @@ -349,7 +349,7 @@ function getUploadFields() $mediaData = $db->pselectRow( "SELECT " . "m.session_id as sessionID, " . - "(SELECT PSCID from candidate WHERE CandID=s.CandID) as pscid, " . + "c.PSCID as pscid, " . "Visit_label as visitLabel, " . "instrument, " . "CenterID as forSite, " . @@ -358,9 +358,10 @@ function getUploadFields() "file_name as fileName, " . "hide_file as hideFile, " . "language_id as language," . - "m.id FROM media m LEFT JOIN session s ON m.session_id = s.ID " . - "WHERE m.id = $idMediaFile", - [] + "m.id FROM media m LEFT JOIN session s ON m.session_id = s.ID + LEFT JOIN candidate c ON (c.CandID=s.CandID) " . + "WHERE m.id = :mediaId", + ['mediaId' => $idMediaFile] ); } diff --git a/modules/survey_accounts/js/survey_accounts_helper.js b/modules/survey_accounts/js/survey_accounts_helper.js index 917e91eef37..ce3acbbad9b 100644 --- a/modules/survey_accounts/js/survey_accounts_helper.js +++ b/modules/survey_accounts/js/survey_accounts_helper.js @@ -16,11 +16,13 @@ $(document).ready(function () { // Handles cases where there was an error on the page and we're resubmitting var email2 = $("input[name=Email2]").val(); var email = $("input[name=Email]").val(); - if (email.length > 0 && email2.length > 0 && email == email2) - { - $('#email_survey').removeAttr('disabled'); - } else { - $('#email_survey').attr('disabled','disabled'); + if (email && email2) { + if (email.length > 0 && email2.length > 0 && email == email2) + { + $('#email_survey').removeAttr('disabled'); + } else { + $('#email_survey').attr('disabled','disabled'); + } } // Reset Test_name so that the template can be loaded by ajax below $("select[name=Test_name]").val(""); @@ -93,7 +95,7 @@ $(document).ready(function () { $("#emailContent").val(content); } ); - + }); }); diff --git a/modules/survey_accounts/jsx/surveyAccountsIndex.js b/modules/survey_accounts/jsx/surveyAccountsIndex.js index 9cbef3bfe9a..15c5400eac4 100644 --- a/modules/survey_accounts/jsx/surveyAccountsIndex.js +++ b/modules/survey_accounts/jsx/surveyAccountsIndex.js @@ -112,7 +112,11 @@ class SurveyAccountsIndex extends Component { options: options.instruments, }}, {label: 'URL', show: true}, - {label: 'Status', show: true}, + {label: 'Status', show: true, filter: { + name: 'Status', + type: 'select', + options: options.statusOptions, + }}, ]; const addSurvey = () => { location.href='/survey_accounts/addSurvey/'; diff --git a/modules/survey_accounts/php/addsurvey.class.inc b/modules/survey_accounts/php/addsurvey.class.inc index 7bd74d60ae9..17e23330d55 100644 --- a/modules/survey_accounts/php/addsurvey.class.inc +++ b/modules/survey_accounts/php/addsurvey.class.inc @@ -162,8 +162,9 @@ class AddSurvey extends \NDB_Form ]; } } - - if ($_REQUEST['fire_away'] !== 'Create survey') { + if (!isset($_REQUEST['fire_away']) + || ($_REQUEST['fire_away'] !== 'Create survey') + ) { if (!filter_var( $values['Email'], FILTER_VALIDATE_EMAIL @@ -241,11 +242,11 @@ class AddSurvey extends \NDB_Form 'CommentID' => $commentID, ] ); + $this->tpl_data['success'] = true; } catch (\DatabaseException $e) { error_log($e->getMessage()); $this->tpl_data['success'] = false; } - $this->tpl_data['success'] = true; if ($email && ($values['send_email'] == 'true')) { $config = \NDB_Config::singleton(); @@ -291,7 +292,7 @@ class AddSurvey extends \NDB_Form "Instrument", array_merge( ['' => ''], - \Utility::getDirectInstruments() + \NDB_BVL_Instrument::getDirectEntryInstrumentNamesList($this->loris) ) ); $this->addBasicText("Email", "Email address"); diff --git a/modules/survey_accounts/php/survey_accounts.class.inc b/modules/survey_accounts/php/survey_accounts.class.inc index 9154921e4a1..7256ccc759e 100644 --- a/modules/survey_accounts/php/survey_accounts.class.inc +++ b/modules/survey_accounts/php/survey_accounts.class.inc @@ -74,14 +74,22 @@ class Survey_Accounts extends \DataFrameworkMenu */ public function getFieldOptions() : array { + $statusOptions = [ + 'Created' => 'Created', + 'Sent' => 'Sent', + 'In Progress' => 'In Progress', + 'Complete' => 'Complete', + ]; + $instruments = \NDB_BVL_Instrument::getDirectEntryInstrumentNamesList( $this->loris ); return [ - 'visits' => \Utility::getVisitList(), - 'instruments' => $instruments, + 'visits' => \Utility::getVisitList(), + 'instruments' => $instruments, + 'statusOptions' => $statusOptions, ]; } diff --git a/php/libraries/BVL_Feedback_Panel.class.inc b/php/libraries/BVL_Feedback_Panel.class.inc index a93a5ea84f3..88988d6d0a7 100644 --- a/php/libraries/BVL_Feedback_Panel.class.inc +++ b/php/libraries/BVL_Feedback_Panel.class.inc @@ -101,7 +101,15 @@ class BVL_Feedback_Panel $summary = $this->feedbackThread->getSummaryOfThreads(); $this->tpl_data['thread_summary_headers'] = json_encode($summary); - $field_names = Utility::getSourcefields($_REQUEST['test_name'] ?? ''); + $test_name = ''; + if (array_key_exists('test_name', $_REQUEST)) { + $test_name = $_REQUEST['test_name']; + } else if (array_key_exists('lorispath', $_REQUEST)) { + $test_name = preg_split("#/#", $_REQUEST['lorispath'])[1] ?? ''; + } + + // Get field names + $field_names = Utility::getSourcefields($test_name); $fields = []; $fields['Across All Fields'] = 'Across All Fields'; foreach ($field_names as $field_name) { diff --git a/php/libraries/LorisForm.class.inc b/php/libraries/LorisForm.class.inc index bc29b94bc18..8a3211d37e8 100644 --- a/php/libraries/LorisForm.class.inc +++ b/php/libraries/LorisForm.class.inc @@ -1592,6 +1592,7 @@ class LorisForm $checked = ''; $value = ''; $disabled = ''; + $required = ''; if (!empty($val)) { $checked = 'checked="checked"'; } @@ -1601,6 +1602,9 @@ class LorisForm if (isset($el['disabled']) || $this->frozen) { $disabled = 'disabled'; } + if (isset($el['required'])) { + $required = 'required'; + } /// XXX: There seems to be a problem when using   to separate the // checkbox from the label. Both Firefox and Chrome will still put a // linebreak between the space and the checkbox. Instead, we wrap use @@ -1609,7 +1613,7 @@ class LorisForm // label it's still allowed to have linebreaks. return "" + . "$disabled $required/>" . " $el[label]"; } diff --git a/php/libraries/LorisFormDictionaryImpl.class.inc b/php/libraries/LorisFormDictionaryImpl.class.inc index 5932bd73deb..62a5979fe58 100644 --- a/php/libraries/LorisFormDictionaryImpl.class.inc +++ b/php/libraries/LorisFormDictionaryImpl.class.inc @@ -131,6 +131,7 @@ trait LorisFormDictionaryImpl $t = new \LORIS\Data\Types\StringType(255); break; case 'header': + case 'hidden': continue 2; default: throw new \LorisException( diff --git a/php/libraries/NDB_BVL_Instrument_LINST.class.inc b/php/libraries/NDB_BVL_Instrument_LINST.class.inc index 87e697a5a2d..1c5251e1b5f 100644 --- a/php/libraries/NDB_BVL_Instrument_LINST.class.inc +++ b/php/libraries/NDB_BVL_Instrument_LINST.class.inc @@ -743,15 +743,15 @@ class NDB_BVL_Instrument_LINST extends \NDB_BVL_Instrument case 'numeric': if ($addElements) { $this->addNumericElement($pieces[1], $pieces[2]); - $this->dictionary[] = new DictionaryItem( - $this->testName."_".$pieces[1], - $pieces[2], - $scope, - new IntegerType(), - new Cardinality(Cardinality::SINGLE), - $pieces[1], - ); } + $this->dictionary[] = new DictionaryItem( + $this->testName."_".$pieces[1], + $pieces[2], + $scope, + new IntegerType(), + new Cardinality(Cardinality::SINGLE), + $pieces[1], + ); if ($firstFieldOfPage) { $this->_requiredElements[] = $fieldname; $firstFieldOfPage = false; diff --git a/test/unittests/LorisForms_Test.php b/test/unittests/LorisForms_Test.php index 276616dbb56..61b269c357e 100644 --- a/test/unittests/LorisForms_Test.php +++ b/test/unittests/LorisForms_Test.php @@ -1336,7 +1336,7 @@ function testCheckboxHTMLWithNoAttributes() $this->form->addCheckbox("abc", "Hello", []); $this->assertEquals( " Hello", + "type=\"checkbox\" /> Hello", $this->form->checkboxHTML($this->form->form['abc']) ); } @@ -1358,7 +1358,7 @@ function testCheckboxHTMLWithAttributesSet() $this->assertEquals( " Hello", + " value=\"value1\" disabled /> Hello", $this->form->checkboxHTML($this->form->form['abc']) ); } diff --git a/tools/importers/CouchDB_MRI_Importer.php b/tools/importers/CouchDB_MRI_Importer.php index 647771a6fb5..c6151c30156 100644 --- a/tools/importers/CouchDB_MRI_Importer.php +++ b/tools/importers/CouchDB_MRI_Importer.php @@ -234,7 +234,10 @@ function _addMRIHeaderInfo($FileObj, $scan_type) $FileObj, 'acquisition_date' ); - $header['FileInsertDate_'.$type] = $FileObj->getParameter('InsertTime'); + $header['FileInsertDate_'.$type] = date( + 'Y-m-d', + $FileObj->getParameter('InsertTime') + ); $header['SeriesDescription_'.$type] = $FileObj->getParameter($ser_desc); $header['SeriesNumber_'.$type] = $FileObj->getParameter($ser_num); $header['EchoTime_'.$type] = number_format(