@@ -149,11 +149,16 @@ public function validateSettings($settings)
149149 }
150150 }
151151 $ headers = ['User-Agent: Redcap ' ];
152+ $ authType = $ settings ['authentication_type ' ];
153+ if ($ authType === 'basic ' ) {
154+ $ authUser = $ settings ['basic_user_id ' ];
155+ $ authPassword = $ settings ['basic_user_password ' ];
156+ $ headers [] = 'Authorization: Basic ' . base64_encode ($ authUser . ': ' . $ authPassword );
157+ }
152158 $ metadata = $ this ->httpGet ($ fhirUrl . '/metadata ' , $ headers );
153159 if ($ metadata === FALSE ) {
154160 $ errors .= "Failed to get metadata for fhir server at ' " . $ fhirUrl . "' \n" ;
155161 }
156- $ authType = $ settings ['authentication_type ' ];
157162 if ($ authType === 'cc ' ) {
158163 $ authEndpoint = $ settings ['cc_token_endpoint ' ];
159164 $ clientId = $ settings ['cc_client_id ' ];
@@ -215,6 +220,17 @@ public function getFhirServerUri()
215220 return $ ontologyServer ;
216221 }
217222
223+ public function hasSnomedSupport ()
224+ {
225+ return $ this ->getSystemSetting ('snomed_support ' );
226+ }
227+
228+ public function hasLoincSupport ()
229+ {
230+ return $ this ->getSystemSetting ('loinc_support ' );
231+ }
232+
233+
218234 /**
219235 * Search API with a search term for a given ontology
220236 * Returns array of results with Notation as key and PrefLabel as value.
@@ -227,9 +243,9 @@ public function searchOntology($valueset_id, $search_term, $result_limit)
227243
228244 // Build URL to call
229245 $ headers = ['User-Agent: Redcap ' ];
230- $ authToken = $ this ->getAuthToken ();
231- if ($ authToken !== false ) {
232- $ headers [] = ' Authorization: Bearer ' . $ this -> getAuthToken () ;
246+ $ authHeader = $ this ->getAuthHeader ();
247+ if ($ authHeader !== false ) {
248+ $ headers [] = $ authHeader ;
233249 }
234250 // Base URL + “/ValueSet/$expand?identifier=VS_ID&filter=SEARCH_TERM”
235251 // need to escape the $expand in the url!
@@ -256,7 +272,7 @@ public function searchOntology($valueset_id, $search_term, $result_limit)
256272 }
257273 // Determine the value
258274 // need to add the system as codes are not unique in SCT
259- $ this_value = $ this_item ['code ' ] . "| " . $ this_item ['display ' ] . " | " . $ this_item [ ' system ' ];
275+ $ this_value = $ this_item ['code ' ] . "| " . $ this_item ['system ' ];
260276
261277 // Add to array
262278 $ results [$ this_value ] = $ this_item ['display ' ];
@@ -322,6 +338,18 @@ public function getOnlineDesignerSection()
322338 {
323339
324340 $ findValueSetService_url = $ this ->getUrl ('FindValueSetService.php ' , false , true );
341+ $ loincSupport = $ this ->hasLoincSupport ();
342+ $ implicitSearchOptions = '' ;
343+ if ($ this ->hasSnomedSupport ()){
344+ $ implicitSearchOptions = $ implicitSearchOptions .
345+ '<option value="refset">SnomedCT Refset</option>\n ' .
346+ '<option value="isa">SnomedCT isa implicit valueset</option>\n ' ;
347+ }
348+ if ($ loincSupport === "ontoserver " || $ loincSupport === "filter " ){
349+ $ implicitSearchOptions = $ implicitSearchOptions .
350+ '<option value="loinc_answer">LOINC implicit answer set</option> ' ;
351+ }
352+
325353 $ onlineDesignerHtml = <<<EOD
326354<script type="text/javascript">
327355
@@ -352,6 +380,14 @@ function move_selected_valueset(event){
352380 return false;
353381 }
354382
383+ function manual_valuset_update(event){
384+ selected_valueset = $('#fhir_value_set').val();
385+ if (selected_valueset){
386+ update_ontology_selection('FHIR', selected_valueset);
387+ }
388+ }
389+
390+
355391 function JSON_STRING(data){
356392 this.data = data;
357393 }
@@ -483,18 +519,16 @@ function show_selected_valueset(event){
483519 class='x-form-text x-form-field' style='padding-right:0;height:22px;width:330px;max-width:330px;'>
484520 <option value=""> -- choose search criteria -- </option>
485521 <option value="name">ValueSet Name</option>
486- <option value="codesystem">By CodeSystem(Name)</option>
487- <option value="refset">SnomedCT Refset</option>
488- <option value="isa">SnomedCT isa implicit valueset</option>
489- <option value="loinc_answer">LOINC implicit answer set</option>
522+ <option value="codesystem">By CodeSystem(Title)</option>
523+ {$ implicitSearchOptions }
490524 </select><br>
491525 <div class="ui-front">
492526 <input id="fhir_valueset_search" class="x-form-text x-form-field" size="25">
493527 <span id="fhir_valueset_search_code" style="display:none"></span>
494528 <a class="ui-button ui-widget ui-corner-all" href="#" onclick="move_selected_valueset(event)">Select</a>
495529 </div>
496530
497- <input id="fhir_value_set" class="x-form-text x-form-field" size="25" type="text" readonly="readonly ">
531+ <input id="fhir_value_set" class="x-form-text x-form-field" size="25" type="text" onchange="manual_valuset_update(event) ">
498532 <a class="ui-button ui-widget ui-corner-all" href="#" onclick="show_selected_valueset(event)">Show Details</a>
499533
500534 <div id="fhir_valueset_dialog" title="ValueSet Details">
@@ -543,11 +577,11 @@ public function getLabelForValue($category, $value)
543577
544578 public function isValidValuesetQueryType ($ type )
545579 {
580+ $ loincSupport = $ this ->hasLoincSupport ();
546581 if ('name ' === $ type ||
547582 'codesystem ' === $ type ||
548- 'refset ' === $ type ||
549- 'isa ' === $ type ||
550- 'loinc_answer ' === $ type ) {
583+ (('refset ' === $ type || 'isa ' === $ type ) && $ this ->hasSnomedSupport ()) ||
584+ (('loinc_answer ' === $ type ) && ('ontoserver ' === $ loincSupport || 'filter ' == $ loincSupport ))) {
551585 return true ;
552586 }
553587 return false ;
@@ -556,6 +590,8 @@ public function isValidValuesetQueryType($type)
556590 public function findValueSet ($ type , $ query )
557591 {
558592 $ contentType = 'application/x-www-form-urlencoded ' ;
593+ $ snomedSupport = $ this ->hasSnomedSupport ();
594+ $ loincSupport = $ this ->hasLoincSupport ();
559595 if ($ type === 'name ' ) {
560596 $ method = "GET " ;
561597 $ params = ['name ' => $ query , '_summary ' => true , '_count ' => 20 ];
@@ -575,14 +611,14 @@ public function findValueSet($type, $query)
575611 };
576612 } elseif ($ type === 'codesystem ' ) {
577613 $ method = "GET " ;
578- $ params = ['name ' => $ query , '_elements ' => 'name ,valueSet ' , '_count ' => 20 ];
614+ $ params = ['title ' => $ query , '_elements ' => 'title ,valueSet ' , '_count ' => 20 ];
579615 $ url = "/CodeSystem " ;
580616 $ processFunction = function ($ data ) {
581617 $ result = [];
582618 if (isset ($ data ['entry ' ])) {
583619 foreach ($ data ['entry ' ] as $ this_entry ) {
584620 if (isset ($ this_entry ['resource ' ]['valueSet ' ])) {
585- $ result [] = ['label ' => $ this_entry ['resource ' ]['name ' ], 'value ' => $ this_entry ['resource ' ]['valueSet ' ]];
621+ $ result [] = ['label ' => $ this_entry ['resource ' ]['title ' ], 'value ' => $ this_entry ['resource ' ]['valueSet ' ]];
586622 }
587623 }
588624 }
@@ -593,6 +629,9 @@ public function findValueSet($type, $query)
593629 return $ result ;
594630 };
595631 } elseif ($ type === 'refset ' ) {
632+ if (!$ snomedSupport ){
633+ return []; // snomed implicit valuesets not supported
634+ }
596635 $ method = "GET " ;
597636 $ params = ['filter ' => $ query , 'url ' => 'http://snomed.info/sct?fhir_vs=refset ' , '_count ' => 20 ];
598637 $ url = '/ValueSet/$expand ' ;
@@ -610,6 +649,9 @@ public function findValueSet($type, $query)
610649 return $ result ;
611650 };
612651 } elseif ($ type === 'isa ' ) {
652+ if (!$ snomedSupport ){
653+ return []; // snomed implicit valuesets not supported
654+ }
613655 $ method = "GET " ;
614656 $ params = ['filter ' => $ query , 'url ' => 'http://snomed.info/sct?fhir_vs ' , '_count ' => 20 ];
615657 $ url = '/ValueSet/$expand ' ;
@@ -627,53 +669,80 @@ public function findValueSet($type, $query)
627669 return $ result ;
628670 };
629671 } elseif ($ type === 'loinc_answer ' ) {
630- $ method = "POST " ;
631- $ contentType = "application/json " ;
632- $ postData = [
633- "resourceType " => "Parameters " ,
634- "parameter " => [
635- ["name " => "filter " , "valueString " => $ query ],
636- ["name " => "_count " , "valueInteger " => 20 ],
637- ["name " => "valueSet " ,
638- "resource " => [
639- "resourceType " => "ValueSet " ,
640- "compose " => [
641- "include " => [[
642- "system " => "http://loinc.org " ,
643- "filter " => [
644- ["property " => "parent " ,
645- "op " => "= " ,
646- "value " => "LL " ]
647- ]
648- ]]
672+ if ('ontoserver ' === $ loincSupport ){
673+ $ method = "POST " ;
674+ $ contentType = "application/json " ;
675+ $ postData = [
676+ "resourceType " => "Parameters " ,
677+ "parameter " => [
678+ ["name " => "filter " , "valueString " => $ query ],
679+ ["name " => "_count " , "valueInteger " => 20 ],
680+ ["name " => "valueSet " ,
681+ "resource " => [
682+ "resourceType " => "ValueSet " ,
683+ "compose " => [
684+ "include " => [[
685+ "system " => "http://loinc.org " ,
686+ "filter " => [
687+ ["property " => "parent " ,
688+ "op " => "= " ,
689+ "value " => "LL " ]
690+ ]
691+ ]]
692+ ]
649693 ]
650694 ]
651695 ]
652- ]
653- ];
654- $ postData = json_encode ($ postData , JSON_UNESCAPED_SLASHES );
655-
656- $ url = '/ValueSet/$expand ' ;
657- $ processFunction = function ($ data ) {
658- $ result = [];
659- if (isset ($ data ['expansion ' ]) && isset ($ data ['expansion ' ]['contains ' ])) {
660- foreach ($ data ['expansion ' ]['contains ' ] as $ this_entry ) {
661- $ result [] = ['label ' => $ this_entry ['display ' ], 'value ' => 'http://loinc.org/vs/ ' . $ this_entry ['code ' ]];
696+ ];
697+ $ postData = json_encode ($ postData , JSON_UNESCAPED_SLASHES );
698+
699+ $ url = '/ValueSet/$expand ' ;
700+ $ processFunction = function ($ data ) {
701+ $ result = [];
702+ if (isset ($ data ['expansion ' ]) && isset ($ data ['expansion ' ]['contains ' ])) {
703+ foreach ($ data ['expansion ' ]['contains ' ] as $ this_entry ) {
704+ $ result [] = ['label ' => $ this_entry ['display ' ], 'value ' => 'http://loinc.org/vs/ ' . $ this_entry ['code ' ]];
705+ }
706+ }
707+ if (empty ($ result )) {
708+ $ result [] = ['label ' => 'No matches found ' , 'value ' => '__NMF__ ' ];
662709 }
663- }
664- if (empty ($ result )) {
665- $ result [] = ['label ' => 'No matches found ' , 'value ' => '__NMF__ ' ];
666- }
667710
668- return $ result ;
669- };
711+ return $ result ;
712+ };
713+ }
714+ elseif ('filter ' === $ loincSupport ){
715+ $ method = "GET " ;
716+ $ params = ['filter ' => $ query , 'url ' => 'http://loinc.org/vs ' , '_count ' => 100 ];
717+ $ url = '/ValueSet/$expand ' ;
718+ $ processFunction = function ($ data ) {
719+ $ result = [];
720+ if (isset ($ data ['expansion ' ]) && isset ($ data ['expansion ' ]['contains ' ])) {
721+ foreach ($ data ['expansion ' ]['contains ' ] as $ this_entry ) {
722+ if (substr ($ this_entry ['code ' ], 0 , 2 ) === 'LL ' ){
723+ $ result [] = ['label ' => $ this_entry ['display ' ], 'value ' => 'http://loinc.org/vs/ ' . $ this_entry ['code ' ]];
724+ }
725+ if (count ($ result ) >= 20 ){
726+ break ;
727+ }
728+ }
729+ }
730+ if (empty ($ result )) {
731+ $ result [] = ['label ' => 'No matches found ' , 'value ' => '__NMF__ ' ];
732+ }
733+ return $ result ;
734+ };
735+ }
736+ else {
737+ return []; // loinc not supported
738+ }
670739 } else {
671740 return ['error ' => "Unknown search type $ type " ];
672741 }
673742 $ headers = ['User-Agent: Redcap ' ];
674- $ authToken = $ this ->getAuthToken ();
675- if ($ authToken !== false ) {
676- $ headers [] = ' Authorization: Bearer ' . $ this -> getAuthToken () ;
743+ $ authHeader = $ this ->getAuthHeader ();
744+ if ($ authHeader !== false ) {
745+ $ headers [] = $ authHeader ;
677746 }
678747 if ('GET ' === $ method ) {
679748 $ fullUrl = $ this ->getFhirServerUri () . $ url . '? ' . http_build_query ($ params );
@@ -693,9 +762,9 @@ public function getValueSetInfo($valueSet)
693762 $ params = ["url " => $ valueSet , "count " => 10 ];
694763 $ fullUrl = $ this ->getFhirServerUri () . '/ValueSet/$expand? ' . http_build_query ($ params );
695764 $ headers = ['User-Agent: Redcap ' ];
696- $ authToken = $ this ->getAuthToken ();
697- if ($ authToken !== false ) {
698- $ headers [] = ' Authorization: Bearer ' . $ this -> getAuthToken () ;
765+ $ authHeader = $ this ->getAuthHeader ();
766+ if ($ authHeader !== false ) {
767+ $ headers [] = $ authHeader ;
699768 }
700769 return $ this ->httpGet ($ fullUrl , $ headers );
701770 }
@@ -798,15 +867,21 @@ public function httpPost($fullUrl, $postData, $contentType, $headers)
798867 }
799868
800869
801- public function getAuthToken ()
870+ public function getAuthHeader ()
802871 {
803872 $ authType = $ this ->getSystemSetting ('authentication_type ' );
804873 if ($ authType === 'cc ' ) {
805874 $ authEndpoint = $ this ->getSystemSetting ('cc_token_endpoint ' );
806875 $ clientId = $ this ->getSystemSetting ('cc_client_id ' );
807876 $ clientSecret = $ this ->getSystemSetting ('cc_client_secret ' );
808877
809- return $ this ->getClientCredentialsToken ($ authEndpoint , $ clientId , $ clientSecret );
878+ $ authToken = $ this ->getClientCredentialsToken ($ authEndpoint , $ clientId , $ clientSecret );
879+ return 'Authorization: Bearer ' . $ authToken ;
880+ }
881+ elseif ($ authType === 'basic ' ) {
882+ $ userId = $ this ->getSystemSetting ('basic_user_id ' );
883+ $ userPassword = $ this ->getSystemSetting ('basic_user_password ' );
884+ return 'Authorization: Basic ' . base64_encode ($ userId . ': ' . $ userPassword );
810885 }
811886 return false ;
812887 }
0 commit comments