Clinical trials viewer downloads and parses information from clinicaltrials.gov at the time of search to populate the graph of clinical trials. FDA information is updated weekly from the Drugs@FDA dataset and the FDA postmarketing commitment data set.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

499 lines
18KB

  1. <?php
  2. $ctviewer = ctv_get_ctviewer_for_address ( $_GET['address'] );
  3. $firststart = ctv_get_first_start_for_address ( $_GET['address'], $ctviewer );
  4. $lastend = ctv_get_last_end_for_address ( $_GET['address'], $ctviewer );
  5. $viewerwidth = ctv_get_width_of_display ($firststart, $lastend);
  6. $ctgtrials = ctv_get_trials_for_address ( $_GET['address'] );
  7. $fdaapps = ctv_get_applications_for_query ( $ctviewer['query'] );
  8. if ( count ($fdaapps) > 0 ) {
  9. $fdaproducts = ctv_get_apps_and_products_for_query ($ctviewer['query']);
  10. $pmcs = ctv_get_apps_and_pmcs_for_query ($ctviewer['query']);
  11. $fdasubs = ctv_get_apps_and_subs_for_query ( $ctviewer['query'] );
  12. $fdadocs = ctv_get_apps_and_docs_for_query ( $ctviewer['query'] );
  13. }
  14. ?><div style="position: fixed; margin-top: 30px; z-index: 700;">
  15. <div class="ctvSticky">
  16. <h1><a href="<?php echo SITE_URL; echo $ctviewer['address']; ?>/">Search term: <?php echo urldecode ($ctviewer['query']); ?></a></h1>
  17. <?php
  18. if (! is_null ($ctviewer['indication'])) {
  19. echo "<p>Indication: " . urldecode ($ctviewer['indication']) . "</p>";
  20. }
  21. ?>
  22. <p><?php echo count ( $ctgtrials ); ?> record(s) found on clinicaltrials.gov</p>
  23. <?php if ( count ($fdaapps) > 0 ) { ?>
  24. <p>Expand or flatten:</p>
  25. <div class="btn-group" role="group" aria-label="FDA info">
  26. <button type="button" class="btn btn-primary" onclick="$('.fdaSubmission').toggleClass('fdaSubmissionFlat').toggleClass('fdaSubmissionStaggered');">FDA submissions</button>
  27. <button type="button" class="btn btn-primary" onclick="$('.fdaDocument').toggleClass('fdaDocumentFlat').toggleClass('fdaDocumentStaggered');">FDA docs</button>
  28. <button type="button" class="btn btn-primary" onclick="$('.fdaPMC').toggleClass('fdaPMCFlat').toggleClass('fdaPMCStaggered');">PMCs</button>
  29. </div>
  30. <p>Yellow: FDA submissions; red: FDA documents; cyan: postmarketing commitments (PMCs)</p>
  31. <?php } ?>
  32. <label for="sortby">Sort trials by</label>
  33. <div class="btn-group btn-group-sm btn-block" id="sortby" role="group" aria-label="Sort by">
  34. <button type="button" id="ctvSortStartDateButton" class="btn btn-primary" onclick="ctv_sort_trials(event, $(this), 'ctvSortStartDate');"<?php
  35. if ($ctviewer['sort_by'] == "ctvSortStartDate") {
  36. echo " disabled";
  37. }
  38. ?>>
  39. Start
  40. </button>
  41. <button type="button" id="ctvSortEndDateButton" class="btn btn-primary" onclick="ctv_sort_trials(event, $(this), 'ctvSortEndDate');"<?php
  42. if ($ctviewer['sort_by'] == "ctvSortEndDate") {
  43. echo " disabled";
  44. }
  45. ?>>
  46. End
  47. </button>
  48. <button type="button" id="ctvSortPhaseButton" class="btn btn-primary" onclick="ctv_sort_trials(event, $(this), 'ctvSortPhase');"<?php
  49. if ($ctviewer['sort_by'] == "ctvSortPhase") {
  50. echo " disabled";
  51. }
  52. ?>>
  53. Phase
  54. </button>
  55. <button type="button" id="ctvSortFundingButton" class="btn btn-primary" onclick="ctv_sort_trials(event, $(this), 'ctvSortFunding');"<?php
  56. if ($ctviewer['sort_by'] == "ctvSortFunding") {
  57. echo " disabled";
  58. }
  59. ?>>
  60. Funding
  61. </button>
  62. </div>
  63. <!-- <label for="colourby">Colour by</label>
  64. <div class="btn-group btn-group-sm btn-block" id="colourby" role="group" aria-label="Colour by">
  65. <button type="button" class="btn btn-primary" disabled>None</button>
  66. <button type="button" class="btn btn-primary">Phase</button>
  67. <button type="button" class="btn btn-primary">Industry</button>
  68. <button type="button" class="btn btn-primary">Type</button>
  69. <button type="button" class="btn btn-primary">Gender</button>
  70. </div> -->
  71. </div>
  72. <?php if ( count ($fdaapps) > 0 ) { ?>
  73. <div class="ctvSticky" style="position: fixed; overflow-y: scroll; height: 500px;">
  74. <p><?php echo count ($fdaapps); ?> FDA application(s) found for this search term</p>
  75. <table class="table table-dark table-hover table-sm">
  76. <thead>
  77. <th scope="col">#</th>
  78. <th scope="col">Product</th>
  79. <th scope="col">Sponsor</th>
  80. <th scope="col">Events</th>
  81. </thead>
  82. <tbody>
  83. <?php
  84. foreach ($fdaapps as $fdaapp) {
  85. echo "<tr class=\"table-info\">";
  86. echo "<td>" . $fdaapp['ApplType'] . " " . $fdaapp['ApplNo'] . "</td>";
  87. echo "<td>" . $fdaapp['DrugName'] . " (" . $fdaapp['ActiveIngredient'] . ")</td>";
  88. echo "<td>" . $fdaapp['SponsorName'] . "</td>";
  89. echo "<td>" . count (ctv_get_submissions_for_product ($fdaapp['ApplNo'])) . " submissions(s)<br>";
  90. echo count (ctv_get_documents_for_product ($fdaapp['ApplNo'])) . " document(s)</td>";
  91. echo "</tr>";
  92. // $fdaproducts = ctv_get_products_for_application ( $fdaapp['ApplNo'] );
  93. $refstandardfound = 0;
  94. foreach ($fdaproducts as $fdaproduct) {
  95. if ( $fdaproduct['ApplNo'] == $fdaapp['ApplNo'] ) {
  96. echo "<tr><td colspan=\"4\">";
  97. echo $fdaproduct['ApplNo'] . "-" . $fdaproduct['ProductNo'];
  98. if ($fdaproduct['ReferenceStandard'] == 1) {
  99. echo "*";
  100. $refstandardfound++;
  101. }
  102. echo " " . $fdaproduct['Form'] . ", ";
  103. echo $fdaproduct['Strength'] . "<br>";
  104. echo "Marketing status: " . $fdaproduct['MarketingStatusDescription'];
  105. echo "</td></tr>";
  106. }
  107. }
  108. if ($refstandardfound > 0) {
  109. echo "<tr><td colspan=\"4\">Asterisk (*) indicates reference standard</td></tr>";
  110. }
  111. }
  112. ?>
  113. </tbody>
  114. </table>
  115. </div>
  116. <?php } ?>
  117. </div>
  118. <div style="position: fixed; margin-top: 30px; z-index: 700; right: 10px;">
  119. <?php
  120. // for each trial, put a hidden div with its details
  121. foreach ( $ctgtrials as $trial ) {
  122. ?><div class="ctvSticky ctvTrialDetails ctvHidden" id="ctvDetails-<?php echo $trial['NCT_Number']; ?>">
  123. <ul class="nav nav-pill nav-fill" style="margin-bottom: 10px;">
  124. <li class="nav-item">
  125. <a class="nav-link" href="#" onclick="event.preventDefault();$('#ctvTrial-<?php echo $trial['NCT_Number']; ?>').prev().click();">Previous (k)</a>
  126. </li>
  127. <li class="nav-item">
  128. <a class="nav-link" href="#" onclick="event.preventDefault();hide_trial_details();">Close (c)</a>
  129. </li>
  130. <li class="nav-item">
  131. <a class="nav-link" href="#" onclick="event.preventDefault();$('#ctvTrial-<?php echo $trial['NCT_Number']; ?>').next().click();">Next (j)</a>
  132. </li>
  133. </ul>
  134. <h2><a href="<?php echo $trial['URL']; ?>" target="_blank"><?php echo $trial['NCT_Number']; ?></a>: <?php echo $trial['Title']; ?></h2>
  135. <p>Other ID(s): <?php echo $trial['Other_IDs']; ?></p>
  136. <p>Status: <?php echo $trial['Status']; ?></p>
  137. <p>Phase: <?php echo $trial['Phases']; ?></p>
  138. <p>Indications: <?php echo $trial['Conditions']; ?></p>
  139. <p>Age: <?php echo $trial['Age']; ?></p>
  140. <hr>
  141. <p>Start: <?php
  142. if ( ! is_null ($trial['Start_Date']) ) {
  143. if ( substr($trial['Start_Date'],8 ,2) == "00" ) {
  144. echo substr($trial['Start_Date'], 0, 7) . "-01";
  145. } else {
  146. echo $trial['Start_Date'];
  147. }
  148. } else {
  149. echo "NS";
  150. }
  151. ?></p>
  152. <p>Primary completion: <?php
  153. if ( ! is_null($trial['Primary_Completion_Date']) ) {
  154. if ( substr($trial['Primary_Completion_Date'],8 ,2) == "00" ) {
  155. echo substr($trial['Primary_Completion_Date'], 0, 7) . "-01";
  156. } else {
  157. echo $trial['Primary_Completion_Date'];
  158. }
  159. } else {
  160. echo "NS";
  161. }
  162. ?></p>
  163. <p>Completion: <?php
  164. if ( ! is_null($trial['Completion_Date']) ) {
  165. if ( substr($trial['Completion_Date'],8 ,2) == "00" ) {
  166. echo substr($trial['Completion_Date'], 0, 7) . "-01";
  167. } else {
  168. echo $trial['Completion_Date'];
  169. }
  170. } else {
  171. echo "NS";
  172. }
  173. ?></p>
  174. <hr>
  175. <p>Enrolment: <?php echo $trial['Enrollment']; ?></p>
  176. <hr>
  177. <p>Funding: <?php echo $trial['Funded_Bys']; ?></p>
  178. <p>Sponsor: <?php echo $trial['Sponsor_Collaborators']; ?></p>
  179. </div>
  180. <?php
  181. }
  182. // For each FDA application, put a hidden div for each postmarketing commitment
  183. if ( count ($fdaapps) > 0 ) {
  184. foreach ($pmcs as $pmc) {
  185. echo "<div class=\"ctvSticky ctvTrialDetails ctvHidden\" id=\"ctvDetails-PMC" . $pmc['CMT_ID'] . "\">";
  186. echo "<a href=\"#\" onclick=\"event.preventDefault();hide_trial_details();\" style=\"margin: 0 1px 4px 10px; float: right;\">[Close]</a>";
  187. echo "<h2>";
  188. if ( $pmc['SUBPART_FLAG'] == "" ) {
  189. echo "Postmarketing commitment ";
  190. } else {
  191. echo "Postmarketing requirement ";
  192. }
  193. echo $pmc['CMT_ID'] . "-" . $pmc['CMT_NUMBER'] . " [" . $fdaapp['ApplNo'] . "]</h2>";
  194. echo "<p>Supplement number: " . $pmc['CMT_DOC_TYPE'] . "-" . $pmc['CMT_DOC_TYPE_NO'] . "</p>";
  195. if ( $pmc['SUBPART_FLAG'] != "" ) {
  196. switch ($pmc['SUBPART_FLAG']) {
  197. case "H":
  198. echo "<p>Required under: <a href=\"http://www.fda.gov/Drugs/GuidanceComplianceRegulatoryInformation/Post-marketingPhaseIVCommitments/ucm070766.htm#q13\" target=\"_blank\">Accelerated approval</a></p>";
  199. break;
  200. case "F":
  201. echo "<p>Required under: <a href=\"http://www.fda.gov/Drugs/GuidanceComplianceRegulatoryInformation/Post-marketingPhaseIVCommitments/ucm070766.htm#q16\" target=\"_blank\">FDAAA section 505(o)(3)</a></p>";
  202. break;
  203. case "P":
  204. echo "<p>Required under: <a href=\"http://www.fda.gov/Drugs/GuidanceComplianceRegulatoryInformation/Post-marketingPhaseIVCommitments/ucm070766.htm#q15\" target=\"_blank\">Pediatric research equity act</a></p>";
  205. break;
  206. case "E":
  207. echo "<p>Required under: <a href=\"http://www.fda.gov/Drugs/GuidanceComplianceRegulatoryInformation/Post-marketingPhaseIVCommitments/ucm070766.htm#q14\" target=\"_blank\">Animal efficacy rule</a></p>";
  208. break;
  209. }
  210. }
  211. echo "<p>Original projected completion date: " . substr($pmc['ORIG_PROJ_COMPL_DATE'], 0, 10 ) . "</p>";
  212. echo "<p>Status: " . $pmc['Status_Desc'] . "</p>";
  213. if ( $pmc['CMT_STATUS_DESC'] != "" ) {
  214. echo "<p>Status description: ";
  215. echo $pmc['CMT_STATUS_DESC'];
  216. echo "</p>";
  217. }
  218. echo "<p>Description: " . $pmc['CMT_DESC'] . "</p>";
  219. echo "<p>Applicant: " . $pmc['APPLICANT'] . "</p>";
  220. echo "<p>Product: " . $pmc['PRODUCT'] . " [" . $pmc['NDA_NUMBER'] . "]</p>";
  221. echo "</div>";
  222. }
  223. }
  224. ?>
  225. </div>
  226. <div style="border: 1px solid #666; min-height: 200px; height: 100%; margin-top: 50px; margin-left: 350px; width: <?php echo $viewerwidth + 350; ?>px; padding-right: 350px;">
  227. <div id="ctvDrugViewGrid" style="padding: 40px 0px 10px 0px; background: url('https://trials.bgcarlisle.com/images/timeline.png'); overflow: visible; width: <?php echo $viewerwidth + 350; ?>px; min-height: 200px;">
  228. <div id="ctvYearMarkerContainer" style="width: <?php echo $viewerwidth; ?>px;">
  229. <?php
  230. // Label the years on the graph
  231. $counter = substr($firststart, 0, 4);
  232. while ($counter <= substr($lastend, 0, 4)) {
  233. echo "<div class=\"ctvYearMarker\">";
  234. echo $counter;
  235. echo "</div>";
  236. $counter++;
  237. }
  238. ?>
  239. </div>
  240. <?php
  241. if ( count ($fdaapps) > 0 ) {
  242. echo "<div class=\"ctvGraphSectionLabel\" style=\"margin-bottom: 70px;\">FDA information</div>";
  243. }
  244. // Put FDA submissions, documents and pmc's on the graph
  245. if ( count ( $fdaapps ) > 0 ) {
  246. echo "<div id=\"fdaInfoContainer\">";
  247. foreach ($fdaapps as $fdaapp) { // Need to optimize ***
  248. // submissions
  249. // $fdasubs = ctv_get_submissions_for_product ($fdaapp['ApplNo']);
  250. foreach ( $fdasubs as $fdasub ) {
  251. if ( $fdaapp['ApplNo'] == $fdasub['ApplNo'] ) {
  252. $subleftyears = ( substr($fdasub['SubmissionStatusDate'], 0, 4) - substr($firststart, 0, 4) ) * 120;
  253. $subleftmonths = substr($fdasub['SubmissionStatusDate'], 5, 2) * 10 - 10;
  254. $subleft = $subleftyears + $subleftmonths;
  255. echo "<div class=\"fdaSubmission fdaSubmissionFlat\" style=\"left: ";
  256. echo $subleft;
  257. echo "px;\" fdaSortDate=\"";
  258. echo $fdasub['ApplNo'] . "-" . $fdasub['SubmissionStatusDate'] . "-1\">";
  259. echo $fdasub['SubmissionType'] . "-" . $fdasub['SubmissionNo'];
  260. echo " (";
  261. echo $fdasub['ReviewPriority'] . " " . $fdasub['SubmissionClassCode'] . " " . $fdasub['SubmissionClassCodeDescription'];
  262. echo ")<br>";
  263. echo "<span class=\"fdaDocApplNo\">" . $fdasub['ApplNo'] . "</span>";
  264. // echo "-";
  265. // echo "<span class=\"fdaProdNo\">" . $fdasub['ProductNo'] . "</span>";
  266. echo "</div>";
  267. }
  268. }
  269. // documents
  270. // $fdadocs = ctv_get_documents_for_product ($fdaapp['ApplNo']);
  271. foreach ($fdadocs as $fdadoc) {
  272. if ( $fdaapp['ApplNo'] == $fdadoc['ApplNo'] ) {
  273. $docleftyears = ( substr($fdadoc['ApplicationDocsDate'], 0, 4) - substr($firststart, 0, 4) ) * 120;
  274. $docleftmonths = substr($fdadoc['ApplicationDocsDate'], 5, 2) * 10 - 10;
  275. $docleft = $docleftyears + $docleftmonths;
  276. echo "<div class=\"fdaDocument fdaDocumentFlat\" style=\"left: " . $docleft . "px;\" fdaSortDate=\"" . $fdasub['ApplNo'] . "-" . $fdadoc['ApplicationDocsDate'] . "-2\">";
  277. echo "<a href=\"" . $fdadoc['ApplicationDocsURL'] . "\" target=\"_blank\">";
  278. echo $fdadoc['ApplicationDocsType_Lookup_Description'] . " (" . $fdadoc['SubmissionType'] . "-" . $fdadoc['SubmissionNo'] . ")";
  279. echo "</a>";
  280. echo "<br>";
  281. echo "<span class=\"fdaDocApplNo\">" . $fdadoc['ApplNo'] . "</span>";
  282. echo "</div>";
  283. }
  284. }
  285. // postmarketing commitments
  286. // $pmcs = ctv_get_pmc_for_nda ($fdaapp['ApplNo']);
  287. foreach ($pmcs as $pmc) {
  288. if ( $fdaapp['ApplNo'] == $pmc['NDA_NUMBER']) {
  289. $pmcleftyears = ( substr($pmc['ORIG_PROJ_COMPL_DATE'], 0, 4) - substr($firststart, 0, 4) ) * 120;
  290. $pmcleftmonths = substr($pmc['ORIG_PROJ_COMPL_DATE'], 5, 2) * 10 - 10;
  291. $pmcleft = $pmcleftyears + $pmcleftmonths;
  292. echo "<div class=\"fdaPMC fdaPMCFlat\" style=\"left: " . $pmcleft . "px;\" fdaSortDate=\"" . $fdaapp['ApplNo'] . "-" . $pmc['ORIG_PROJ_COMPL_DATE'] ."-3\" onclick=\"show_trial_details('PMC" . $pmc['CMT_ID'] . "');\">";
  293. if ( $pmc['SUBPART_FLAG'] == "" ) {
  294. echo "Postmarketing commitment ";
  295. } else {
  296. echo "Postmarketing requirement ";
  297. }
  298. echo $pmc['CMT_ID'] . "-" . $pmc['CMT_NUMBER'] . " / " . $pmc['CMT_DOC_TYPE'] . "-" . $pmc['CMT_DOC_TYPE_NO'] . " (" . $pmc['Status_Desc'] . ")";
  299. echo "<br>";
  300. echo "<span class=\"fdaDocApplNo\">" . $fdaapp['ApplNo'] . "</span>";
  301. echo "</div>";
  302. }
  303. }
  304. }
  305. echo "</div><hr>";
  306. }
  307. ?>
  308. <div class="ctvGraphSectionLabel" style="margin-bottom: 20px;">Trial records from clinicaltrials.gov</div>
  309. <?php
  310. // Now put the trials on the graph
  311. foreach ( $ctgtrials as $trial ) {
  312. // Get the right and left bounds
  313. // There are 6 possible cases, numbered below
  314. if ( ! is_null ($trial['Start_Date']) ) { // There is a start date
  315. if ( ! is_null ($trial['Primary_Completion_Date']) ) { // There is a start date and a primary completion date
  316. // 1. Make left and right bounded by start and primary completion dates
  317. $lmyears = ( substr($trial['Start_Date'], 0, 4) - substr($firststart, 0, 4) ) * 120;
  318. $lmmonths = substr($trial['Start_Date'], 5, 2) * 10 - 10;
  319. $leftmargin = $lmyears + $lmmonths;
  320. $trialwidth = floor ( ( strtotime(substr($trial['Primary_Completion_Date'], 0, 7) . "-01") - strtotime(substr($trial['Start_Date'], 0, 7) . "-01") ) / 60 / 60 / 24 / 365 * 120 );
  321. $noDateInfo = "";
  322. } else { // There is a start date but no primary completion date
  323. if ( ! is_null ($trial['Completion_Date']) ) { // There is a start date and a completion date
  324. // 2. Make left and right bounded by start and completion date
  325. $lmyears = ( substr($trial['Start_Date'], 0, 4) - substr($firststart, 0, 4) ) * 120;
  326. $lmmonths = substr($trial['Start_Date'], 5, 2) * 10 - 10;
  327. $leftmargin = $lmyears + $lmmonths;
  328. $trialwidth = floor ( ( strtotime(substr($trial['Completion_Date'], 0, 7) . "-01") - strtotime(substr($trial['Start_Date'], 0, 7) . "-01") ) / 60 / 60 / 24 / 365 * 120 );
  329. $noDateInfo = "";
  330. } else { // There is a start date, but no completion date of any kind
  331. // 3. Make it fade away to the right
  332. $lmyears = ( substr($trial['Start_Date'], 0, 4) - substr($firststart, 0, 4) ) * 120;
  333. $lmmonths = substr($trial['Start_Date'], 5, 2) * 10 - 10;
  334. $leftmargin = $lmyears + $lmmonths;
  335. $trialwidth = 250;
  336. $noDateInfo = " NoEndDate";
  337. }
  338. }
  339. } else { // No start date
  340. if ( ! is_null ($trial['Primary_Completion_Date']) ) { // No start date, but there is a primary completion date
  341. // 4. Make it fade away to the left
  342. $lmyears = ( substr($trial['Primary_Completion_Date'], 0, 4) - substr($firststart, 0, 4) ) * 120;
  343. $lmmonths = substr($trial['Primary_Completion_Date'], 5, 2) * 10 - 10;
  344. $leftmargin = $lmyears + $lmmonths - 250;
  345. $noDateInfo = " NoStartDate";
  346. } else { // No start date, no primary completion date
  347. if ( ! is_null ($trial['Completion_Date']) ) { // No start date, but there is a completion date
  348. // 5. Make it fade away to the left
  349. $lmyears = ( substr($trial['Completion_Date'], 0, 4) - substr($firststart, 0, 4) ) * 120;
  350. $lmmonths = substr($trial['Completion_Date'], 5, 2) * 10 - 10;
  351. $leftmargin = $lmyears + $lmmonths - 250;
  352. $noDateInfo = " NoStartDate";
  353. } else { // No dates of any kind
  354. // 6. Make it fade away both ways
  355. $leftmargin = 0;
  356. $trialwidth = 250;
  357. $noDateInfo = " NoDates";
  358. }
  359. }
  360. }
  361. // Now you have the left and right bounds
  362. // Get stuff for colouring (to-do!)
  363. echo "<div class=\"ctvTrial" . $noDateInfo . "\" id=\"ctvTrial-" . $trial['NCT_Number'] . "\" style=\"margin-left: " . $leftmargin . "px; width: " . $trialwidth . "px;\" onclick=\"show_trial_details('" . $trial['NCT_Number'] . "');\" ctvSortStartDate=\"" . $trial['Start_Date'] . "\" ctvSortEndDate=\"" . $trial['End_Date'] . "\" ctvSortPhase=\"" . $trial['Phases'] . "-" . $trial['Start_Date'] . "\" ctvSortFunding=\"" . $trial['Funded_Bys'] . "-" . $trial['Start_Date'] . "\">";
  364. echo $trial['NCT_Number'] . " | " . $trial['Phases'] . " | " . $trial['Conditions'];
  365. echo "</div>";
  366. }
  367. ?>
  368. </div>
  369. </div>