AdminInterface.class.php 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820
  1. <?php
  2. namespace Models {
  3. require_once 'Models/User.class.php';
  4. require_once 'Tools/Crypto.class.php';
  5. class AdminInterface {
  6. //
  7. protected $DataInterface;
  8. /**
  9. *
  10. */
  11. public function __construct($DataInterface) {
  12. $this->DataInterface = $DataInterface;
  13. }
  14. /**
  15. * Check login/password and create JWT token.
  16. */
  17. public function adminLogin(&$User, $email, $clearPassword) {
  18. $statement = $this->DataInterface->DatabaseConnection->prepare(
  19. "SELECT
  20. ID, password, firstname, lastname
  21. FROM
  22. user
  23. WHERE
  24. active = 1 AND
  25. email = '$email' AND
  26. type = 'imt-master'"
  27. );
  28. if(!$statement->execute()) {
  29. $results = Array('result' => 'ERROR', 'reason' => 'internal_error', 'message' => 'Database error', 'data' => $statement->errorInfo());
  30. }
  31. else {
  32. $results = $statement->fetchAll(\PDO::FETCH_ASSOC);
  33. if(count($results)){
  34. if(\Tools\Crypto::verify($clearPassword, $results[0]['password'])) {
  35. // Generate JWT token
  36. $issuer_claim = \Config\Settings::getTokenIssuer();
  37. $audience_claim = \Config\Settings::getAdminTokenAudience();
  38. $issuedat_claim = time(); // issued at
  39. $notbefore_claim = $issuedat_claim + \Config\Settings::getTokenNotBefore();
  40. $expire_claim = $issuedat_claim + \Config\Settings::getTokenExpiration();
  41. $token = array(
  42. "iss" => $issuer_claim,
  43. "aud" => $audience_claim,
  44. "iat" => $issuedat_claim,
  45. "nbf" => $notbefore_claim,
  46. "exp" => $expire_claim,
  47. "data" => array(
  48. "ID" => $results[0]['ID'],
  49. "firstname" => $results[0]['firstname'],
  50. "lastname" => $results[0]['lastname'],
  51. "email" => $email
  52. )
  53. );
  54. $jwt = \Firebase\JWT\JWT::encode($token, \Config\Settings::getTokenPrivateKey());
  55. // OK
  56. $results = Array(
  57. "result" => "OK",
  58. "token" => $jwt,
  59. "email" => $email,
  60. "expireAt" => $expire_claim
  61. );
  62. }
  63. else {
  64. $results = Array('result' => 'ERROR', 'reason' => 'bad_password', 'message' => 'Invalid password');
  65. }
  66. }
  67. else {
  68. $results = Array('result' => 'ERROR', 'reason' => 'unknown', 'message' => 'No such user');
  69. }
  70. }
  71. return $results;
  72. }
  73. /**
  74. * Logout.
  75. */
  76. public function adminLogout(&$User) {
  77. $User->logout();
  78. return Array('result' => 'OK');
  79. }
  80. /**
  81. * Get profile data.
  82. */
  83. public function adminProfileGet($User) {
  84. $userID = $User->ID;
  85. // OK
  86. return array(
  87. 'result' => 'OK',
  88. 'ID' => $User->ID,
  89. 'firstname' => $User->firstname,
  90. 'lastname' => $User->lastname,
  91. 'email' => $User->email
  92. );
  93. }
  94. /**
  95. * Get common data.
  96. */
  97. public function adminCommonGet($User) {
  98. $userID = $User->ID;
  99. $statement = $this->DataInterface->DatabaseConnection->prepare(
  100. "SELECT data FROM settings"
  101. );
  102. if(!$statement->execute()) {
  103. $results = Array('result' => 'ERROR', 'reason' => 'internal_error', 'message' => 'Database error', 'data' => $statement->errorInfo());
  104. }
  105. $settings = json_decode($statement->fetchAll(\PDO::FETCH_ASSOC)[0]['data'], JSON_NUMERIC_CHECK);
  106. // OK
  107. return array(
  108. 'result' => 'OK',
  109. 'ID' => $User->ID,
  110. 'firstname' => $User->firstname,
  111. 'lastname' => $User->lastname,
  112. 'email' => $User->email,
  113. 'settings' => $settings
  114. );
  115. }
  116. /**
  117. * Get export data.
  118. */
  119. public function adminExportGet($User) {
  120. $userID = $User->ID;
  121. $statement = $this->DataInterface->DatabaseConnection->prepare(
  122. "SELECT * FROM user WHERE type = 'physician'"
  123. );
  124. if(!$statement->execute()) {
  125. $results = Array('result' => 'ERROR', 'reason' => 'internal_error', 'message' => 'Database error', 'data' => $statement->errorInfo());
  126. }
  127. $users = $statement->fetchAll(\PDO::FETCH_ASSOC);
  128. // OK
  129. return array(
  130. 'result' => 'OK',
  131. 'users' => $users,
  132. );
  133. }
  134. /**
  135. * Post export data.
  136. */
  137. public function adminExportPost($User, $data) {
  138. $userID = $User->ID;
  139. return $this->exportByID($data['ID']);
  140. }
  141. public function exportByID($ID) {
  142. $statement = $this->DataInterface->DatabaseConnection->prepare(
  143. "SELECT * FROM user WHERE ID = $ID"
  144. );
  145. if(!$statement->execute()) {
  146. $results = Array('result' => 'ERROR', 'reason' => 'internal_error', 'message' => 'Database error', 'data' => $statement->errorInfo());
  147. }
  148. $user = $statement->fetchAll(\PDO::FETCH_ASSOC)[0];
  149. $prefix = date('Y-m-d').'_'.str_replace([' ','\''], '_', $user['firstname'].'_'.$user['lastname']);
  150. $od = '../../storage/tmp/'.$prefix.'_'.$ID.'/';
  151. \Tools\FS::mkpath($od);
  152. $data = [];
  153. // header
  154. $data[] =
  155. 'Visit_PatientID,Visit_Date,Visit_Created,Visit_Area,'.
  156. 'Media_Location,Media_Incidence,Media_Filename,Media_Width,Media_Height,Media_PixelWidth,Media_PixelHeight,Media_FrameCount,Media_FramePerSecond,'.
  157. 'Measure_Created,Measure_Frame,Measure_Distance,Measure_ImtMean,Measure_ImtMax,Measure_ImtStddev,Measure_IntimaMean,Measure_MediaMean,Measure_NearWall,Measure_QualityIndex,Measure_NumberOfPoints';
  158. // visit
  159. $statement = $this->DataInterface->DatabaseConnection->prepare("
  160. SELECT patient.patientID, visit.*
  161. FROM patient, visit
  162. WHERE patient.ID = visit.fk_patient
  163. AND visit.area = 'carotid'
  164. AND patient.fk_user = $ID
  165. ");
  166. // Error check
  167. if(!$statement->execute()) {
  168. return ['result' => 'ERROR', 'reason' => 'internal_error', 'message' => 'Database error', 'data' => $statement->errorInfo()];
  169. }
  170. $visits = $statement->fetchAll(\PDO::FETCH_ASSOC);
  171. foreach($visits as $visit) {
  172. $fk_visit = $visit['ID'];
  173. // media
  174. $statement = $this->DataInterface->DatabaseConnection->prepare("
  175. SELECT media.*
  176. FROM media
  177. WHERE fk_visit = $fk_visit
  178. ");
  179. // Error check
  180. if(!$statement->execute()) {
  181. return ['result' => 'ERROR', 'reason' => 'internal_error', 'message' => 'Database error', 'data' => $statement->errorInfo()];
  182. }
  183. $medias = $statement->fetchAll(\PDO::FETCH_ASSOC);
  184. foreach($medias as $media) {
  185. $fk_media = $media['ID'];
  186. // measure
  187. $statement = $this->DataInterface->DatabaseConnection->prepare("
  188. SELECT measure.*
  189. FROM measure
  190. WHERE fk_media = $fk_media
  191. AND type = 'imt'
  192. ");
  193. // Error check
  194. if(!$statement->execute()) {
  195. return ['result' => 'ERROR', 'reason' => 'internal_error', 'message' => 'Database error', 'data' => $statement->errorInfo()];
  196. }
  197. $measures = $statement->fetchAll(\PDO::FETCH_ASSOC);
  198. // save file
  199. if(count($measures)) {
  200. copy('../../storage/media/'.$visit['ID'].'/'.$media['filename'], $od.'/'.$media['filename']);
  201. }
  202. foreach($measures as $measure) {
  203. $V['Visit_PatientID'] = $visit['patientID'];
  204. $V['Visit_Date'] = $visit['visitDate'];
  205. $V['Visit_Created'] = $visit['created'];
  206. $V['Visit_Area'] = $visit['area'];
  207. $V['Media_Location'] = $media['location'];
  208. $V['Media_Incidence'] = $media['incidence'];
  209. $V['Media_Filename'] = $media['filename'];
  210. $metrics = json_decode($media['metrics']);
  211. $V['Media_Width'] = $metrics->width;
  212. $V['Media_Height'] = $metrics->height;
  213. $V['Media_PixelWidth'] = $metrics->pxwidth;
  214. $V['Media_PixelHeight'] = $metrics->pxheight;
  215. $V['Media_FrameCount'] = $metrics->frameCount;
  216. $V['Media_FramePerSecond'] = $metrics->fps;
  217. $V['Measure_Created'] = $measure['created'];
  218. $V['Measure_Frame'] = $measure['frame'];
  219. $computation = json_decode($measure['computation']);
  220. $V['Measure_Distance'] = $computation->distance;
  221. $V['Measure_ImtMean'] = $computation->imt_mean;
  222. $V['Measure_ImtMax'] = $computation->imt_max;
  223. $V['Measure_ImtStddev'] = $computation->imt_stddev;
  224. $V['Measure_IntimaMean'] = $computation->intima_mean;
  225. $V['Measure_MediaMean'] = $computation->media_mean;
  226. $V['Measure_Location'] = $computation->nearWall?'Proximal':'Distal';
  227. $V['Measure_QualityIndex'] = $computation->qualityIndex;
  228. $V['Measure_NumberOfPoints'] = $computation->numberOfPoints;
  229. //$data[] = $V;
  230. $data[] = implode(",", $V);
  231. }
  232. }
  233. }
  234. unlink('../../storage/tmp/'.$prefix.'_'.$ID);
  235. // make archive
  236. $dst = '../../storage/tmp/'.$prefix.'_'.$ID.'.zip';
  237. unlink($dst);
  238. $cmdLine = 'cd ../../storage/tmp && zip -r '.$prefix.'_'.$ID.'.zip '.$prefix.'_'.$ID.'/ 2>&1';
  239. $output=null;
  240. $retval=null;
  241. exec($cmdLine, $output, $retval);
  242. // error
  243. if($retval !== 0 || count($output)<1) {
  244. return [
  245. 'result' => 'ERROR',
  246. 'cmdLine' => $cmdLine,
  247. 'output' => $output,
  248. 'retval' => $retval
  249. ];
  250. }
  251. // make csv
  252. unlink('../../storage/tmp/'.$prefix.'_'.$ID.'.csv');
  253. file_put_contents('../../storage/tmp/'.$prefix.'_'.$ID.'.csv', implode("\n", $data));
  254. // OK
  255. return array(
  256. 'result' => 'OK',
  257. 'ID' => $ID,
  258. 'data' => $data,
  259. 'csv' => 'tmp/'.$prefix.'_'.$ID.'.csv',
  260. 'zip' => 'tmp/'.$prefix.'_'.$ID.'.zip'
  261. );
  262. }
  263. /**
  264. * Post common data.
  265. */
  266. public function adminCommonPost($User, $data) {
  267. $userID = $User->ID;
  268. // update settings
  269. $statement = $this->DataInterface->DatabaseConnection->prepare(
  270. "UPDATE settings SET data = :data"
  271. );
  272. $data = json_encode($data['data'], JSON_NUMERIC_CHECK);
  273. $statement->bindParam(':data', $data);
  274. // Error check
  275. if(!$statement->execute()) {
  276. return ['result' => 'ERROR', 'reason' => 'internal_error', 'message' => 'Database error', 'data' => $statement->errorInfo()];
  277. }
  278. // OK
  279. return array(
  280. 'result' => 'OK',
  281. 'data' => $data
  282. );
  283. }
  284. /**
  285. *
  286. */
  287. public function adminCtParamsGet($User) {
  288. $userID = $User->ID;
  289. $statement = $this->DataInterface->DatabaseConnection->prepare(
  290. "SELECT * FROM clinical_trial"
  291. );
  292. // Error check
  293. if(!$statement->execute()) {
  294. return ['result' => 'ERROR', 'reason' => 'internal_error', 'message' => 'Database error', 'data' => $statement->errorInfo()];
  295. }
  296. $settings = $statement->fetchAll(\PDO::FETCH_ASSOC)[0];
  297. $settings['comment'] = stripslashes($settings['comment']);
  298. // OK
  299. return array(
  300. 'result' => 'OK',
  301. 'settings' => $settings
  302. );
  303. }
  304. /**
  305. *
  306. */
  307. public function adminCtStatsGet($User) {
  308. $userID = $User->ID;
  309. // patients
  310. $statement = $this->DataInterface->DatabaseConnection->prepare("
  311. SELECT DATE_FORMAT(visit.created, '%Y-%m') AS m, COUNT(visit.ID) AS patients
  312. FROM visit, patient, user
  313. WHERE visit.fk_patient = patient.ID AND patient.fk_user = user.ID AND user.type = 'investigator'
  314. GROUP BY DATE_FORMAT(visit.created, '%Y-%m')
  315. ");
  316. // Error check
  317. if(!$statement->execute()) {
  318. return ['result' => 'ERROR', 'reason' => 'internal_error', 'message' => 'Database error', 'data' => $statement->errorInfo()];
  319. }
  320. $resPatients = $statement->fetchAll(\PDO::FETCH_ASSOC);
  321. // measures
  322. $statement = $this->DataInterface->DatabaseConnection->prepare("
  323. SELECT DATE_FORMAT(measure.created, '%Y-%m') AS m, COUNT(measure.ID) AS measures
  324. FROM measure, user
  325. WHERE measure.fk_user = user.ID AND user.type = 'reader'
  326. GROUP BY DATE_FORMAT(measure.created, '%Y-%m')
  327. ");
  328. // Error check
  329. if(!$statement->execute()) {
  330. return ['result' => 'ERROR', 'reason' => 'internal_error', 'message' => 'Database error', 'data' => $statement->errorInfo()];
  331. }
  332. $resMeasures = $statement->fetchAll(\PDO::FETCH_ASSOC);
  333. $patients = [];
  334. $start = (new \DateTime($resPatients[0]['m'].'-01'))->modify('first day of this month');
  335. $end = (new \DateTime(date('Y-m-d')))->modify('first day of next month');
  336. $interval = \DateInterval::createFromDateString('1 month');
  337. $period = new \DatePeriod($start, $interval, $end);
  338. foreach($period as $dt) {
  339. $patients[] = array('m' => $dt->format("Y-m"), 'patients' => 0, 'measures' => 0);
  340. }
  341. foreach($resPatients as $R) {
  342. foreach($patients as &$P) {
  343. if($P['m'] == $R['m']) {
  344. $P['patients'] = intval($R['patients']);
  345. }
  346. }
  347. }
  348. foreach($resMeasures as $R) {
  349. foreach($patients as &$P) {
  350. if($P['m'] == $R['m']) {
  351. $P['measures'] = intval($R['measures']);
  352. }
  353. }
  354. }
  355. // OK
  356. return array(
  357. 'result' => 'OK',
  358. 'patients' => $patients
  359. );
  360. }
  361. /**
  362. *
  363. */
  364. public function adminPhyStatsGet($User) {
  365. $userID = $User->ID;
  366. // patients
  367. $statement = $this->DataInterface->DatabaseConnection->prepare("
  368. SELECT DATE_FORMAT(visit.created, '%Y-%m') AS m, COUNT(visit.ID) AS patients
  369. FROM visit, patient, user
  370. WHERE visit.fk_patient = patient.ID AND patient.fk_user = user.ID AND user.type = 'physician'
  371. GROUP BY DATE_FORMAT(visit.created, '%Y-%m')
  372. ");
  373. // Error check
  374. if(!$statement->execute()) {
  375. return ['result' => 'ERROR', 'reason' => 'internal_error', 'message' => 'Database error', 'data' => $statement->errorInfo()];
  376. }
  377. $resPatients = $statement->fetchAll(\PDO::FETCH_ASSOC);
  378. // measures
  379. $statement = $this->DataInterface->DatabaseConnection->prepare("
  380. SELECT DATE_FORMAT(measure.created, '%Y-%m') AS m, COUNT(measure.ID) AS measures
  381. FROM measure, user
  382. WHERE measure.fk_user = user.ID AND user.type = 'physician'
  383. GROUP BY DATE_FORMAT(measure.created, '%Y-%m')
  384. ");
  385. // Error check
  386. if(!$statement->execute()) {
  387. return ['result' => 'ERROR', 'reason' => 'internal_error', 'message' => 'Database error', 'data' => $statement->errorInfo()];
  388. }
  389. $resMeasures = $statement->fetchAll(\PDO::FETCH_ASSOC);
  390. $patients = [];
  391. $start = (new \DateTime($resPatients[0]['m'].'-01'))->modify('first day of this month');
  392. $end = (new \DateTime(date('Y-m-d')))->modify('first day of next month');
  393. $interval = \DateInterval::createFromDateString('1 month');
  394. $period = new \DatePeriod($start, $interval, $end);
  395. foreach($period as $dt) {
  396. $patients[] = array('m' => $dt->format("Y-m"), 'patients' => 0, 'measures' => 0);
  397. }
  398. foreach($resPatients as $R) {
  399. foreach($patients as &$P) {
  400. if($P['m'] == $R['m']) {
  401. $P['patients'] = intval($R['patients']);
  402. }
  403. }
  404. }
  405. foreach($resMeasures as $R) {
  406. foreach($patients as &$P) {
  407. if($P['m'] == $R['m']) {
  408. $P['measures'] = intval($R['measures']);
  409. }
  410. }
  411. }
  412. // OK
  413. return array(
  414. 'result' => 'OK',
  415. 'patients' => $patients
  416. );
  417. }
  418. /**
  419. *
  420. */
  421. public function adminCtUsersGet($User) {
  422. $userID = $User->ID;
  423. $statement = $this->DataInterface->DatabaseConnection->prepare(
  424. "SELECT COUNT(ID) AS cnt FROM user WHERE type = 'cro'"
  425. );
  426. // Error check
  427. if(!$statement->execute()) {
  428. return ['result' => 'ERROR', 'reason' => 'internal_error', 'message' => 'Database error', 'data' => $statement->errorInfo()];
  429. }
  430. $admin = $statement->fetchAll(\PDO::FETCH_ASSOC)[0]['cnt'];
  431. $statement = $this->DataInterface->DatabaseConnection->prepare(
  432. "SELECT COUNT(ID) AS cnt FROM user WHERE type = 'investigator'"
  433. );
  434. // Error check
  435. if(!$statement->execute()) {
  436. return ['result' => 'ERROR', 'reason' => 'internal_error', 'message' => 'Database error', 'data' => $statement->errorInfo()];
  437. }
  438. $investigator = $statement->fetchAll(\PDO::FETCH_ASSOC)[0]['cnt'];
  439. $statement = $this->DataInterface->DatabaseConnection->prepare(
  440. "SELECT COUNT(ID) AS cnt FROM user WHERE type = 'reader'"
  441. );
  442. // Error check
  443. if(!$statement->execute()) {
  444. return ['result' => 'ERROR', 'reason' => 'internal_error', 'message' => 'Database error', 'data' => $statement->errorInfo()];
  445. }
  446. $reader = $statement->fetchAll(\PDO::FETCH_ASSOC)[0]['cnt'];
  447. // OK
  448. return array(
  449. 'result' => 'OK',
  450. 'data' => [
  451. 'admin' => $admin,
  452. 'investigator' => $investigator,
  453. 'reader' => $reader
  454. ]
  455. );
  456. }
  457. /**
  458. *
  459. */
  460. public function adminCreditGet($User, $ID) {
  461. $userID = $User->ID;
  462. // total purchased credits
  463. $statement = $this->DataInterface->DatabaseConnection->prepare(
  464. "SELECT SUM(count) AS purchased FROM credit WHERE ID_user = :fk_user"
  465. );
  466. $statement->bindParam(':fk_user', $ID);
  467. // Error check
  468. if(!$statement->execute()) {
  469. return ['result' => 'ERROR', 'reason' => 'internal_error', 'message' => 'Database error', 'data' => $statement->errorInfo()];
  470. }
  471. $purchased = intval($statement->fetchAll(\PDO::FETCH_ASSOC)[0]['purchased']);
  472. // total used credits
  473. $statement = $this->DataInterface->DatabaseConnection->prepare(
  474. "SELECT COUNT(ID) AS used FROM credit_usage WHERE fk_user = :fk_user"
  475. );
  476. $statement->bindParam(':fk_user', $ID);
  477. // Error check
  478. if(!$statement->execute()) {
  479. return ['result' => 'ERROR', 'reason' => 'internal_error', 'message' => 'Database error', 'data' => $statement->errorInfo()];
  480. }
  481. $used = intval($statement->fetchAll(\PDO::FETCH_ASSOC)[0]['used']);
  482. // credit
  483. $statement = $this->DataInterface->DatabaseConnection->prepare(
  484. "SELECT * FROM credit WHERE ID_user = $ID ORDER BY stamp DESC"
  485. );
  486. // Error check
  487. if(!$statement->execute()) {
  488. return ['result' => 'ERROR', 'reason' => 'internal_error', 'message' => 'Database error', 'data' => $statement->errorInfo()];
  489. }
  490. $credit = $statement->fetchAll(\PDO::FETCH_ASSOC);
  491. // OK
  492. return array(
  493. 'result' => 'OK',
  494. 'credit' => $credit,
  495. 'purchased' => $purchased,
  496. 'used' => $used
  497. );
  498. }
  499. /**
  500. *
  501. */
  502. public function adminCreditPost($User, $data) {
  503. $userID = $User->ID;
  504. $customerID = $data['ID'];
  505. $count = $data['count'];
  506. // credit
  507. $statement = $this->DataInterface->DatabaseConnection->prepare(
  508. "INSERT INTO credit(ID_user, count) VALUES($customerID, $count)"
  509. );
  510. // Error check
  511. if(!$statement->execute()) {
  512. return ['result' => 'ERROR', 'reason' => 'internal_error', 'message' => 'Database error', 'data' => $statement->errorInfo()];
  513. }
  514. // OK
  515. return array(
  516. 'result' => 'OK',
  517. 'credit' => $credit
  518. );
  519. }
  520. /**
  521. *
  522. */
  523. public function adminCustomerGet($User, $who) {
  524. $userID = $User->ID;
  525. if($who=='physician') {
  526. // customers
  527. $statement = $this->DataInterface->DatabaseConnection->prepare(
  528. "SELECT ID, firstname, lastname, email FROM user WHERE type = 'physician' ORDER BY lastname, firstname"
  529. );
  530. // Error check
  531. if(!$statement->execute()) {
  532. return ['result' => 'ERROR', 'reason' => 'internal_error', 'message' => 'Database error', 'data' => $statement->errorInfo()];
  533. }
  534. $customer = $statement->fetchAll(\PDO::FETCH_ASSOC);
  535. }
  536. else {
  537. // customers
  538. $statement = $this->DataInterface->DatabaseConnection->prepare(
  539. "SELECT * FROM user WHERE type = 'cro' ORDER BY ID LIMIT 0,1"
  540. );
  541. // Error check
  542. if(!$statement->execute()) {
  543. return ['result' => 'ERROR', 'reason' => 'internal_error', 'message' => 'Database error', 'data' => $statement->errorInfo()];
  544. }
  545. $customer = $statement->fetchAll(\PDO::FETCH_ASSOC);
  546. // clinical trial
  547. $statement = $this->DataInterface->DatabaseConnection->prepare(
  548. "SELECT max_readers, max_investigators FROM clinical_trial"
  549. );
  550. // Error check
  551. if(!$statement->execute()) {
  552. return ['result' => 'ERROR', 'reason' => 'internal_error', 'message' => 'Database error', 'data' => $statement->errorInfo()];
  553. }
  554. $res = $statement->fetchAll(\PDO::FETCH_ASSOC);
  555. if(count($res)) {
  556. $customer[0]['max_readers'] = $res[0]['max_readers'];
  557. $customer[0]['max_investigators'] = $res[0]['max_investigators'];
  558. }
  559. else {
  560. $customer[0]['max_readers'] = 1;
  561. $customer[0]['max_investigators'] = 1;
  562. }
  563. $credits = $this->adminCreditGet($User, $customer[0]['ID']);
  564. if($credits['result'] == 'ERROR') {
  565. return $credits;
  566. }
  567. $customer[0]['credits'] = $credits;
  568. }
  569. // OK
  570. return array(
  571. 'result' => 'OK',
  572. 'who' => $who,
  573. 'customer' => $customer
  574. );
  575. }
  576. /**
  577. * Get pacs data.
  578. */
  579. public function adminPacsGet($User) {
  580. $userID = $User->ID;
  581. // customers
  582. $statement = $this->DataInterface->DatabaseConnection->prepare(
  583. "SELECT ID AS physicianID, firstname, lastname, email FROM user WHERE type = 'physician' ORDER BY lastname, firstname"
  584. );
  585. // Error check
  586. if(!$statement->execute()) {
  587. return ['result' => 'ERROR', 'reason' => 'internal_error', 'message' => 'Database error', 'data' => $statement->errorInfo()];
  588. }
  589. $customer = $statement->fetchAll(\PDO::FETCH_ASSOC);
  590. // pacs
  591. $statement = $this->DataInterface->DatabaseConnection->prepare(
  592. "SELECT * FROM settings_pacs WHERE fk_physician IS NOT NULL AND fk_center IS NULL ORDER BY fk_physician"
  593. );
  594. // Error check
  595. if(!$statement->execute()) {
  596. return ['result' => 'ERROR', 'reason' => 'internal_error', 'message' => 'Database error', 'data' => $statement->errorInfo()];
  597. }
  598. $pacs = $statement->fetchAll(\PDO::FETCH_ASSOC);
  599. foreach($pacs as &$p) {
  600. $p['data'] = json_decode($p['data']);
  601. }
  602. // OK
  603. return array(
  604. 'result' => 'OK',
  605. 'ourAET' => 'IIMT',
  606. 'customer' => $customer,
  607. 'pacs' => $pacs
  608. );
  609. }
  610. /**
  611. * Post pacs data.
  612. */
  613. public function adminPacsPost($User, $data) {
  614. $userID = $User->ID;
  615. $fk_physician = $data['data']['physicianID'];
  616. // insert
  617. if(intval($data['data']['PACSID'])==0) {
  618. $statement = $this->DataInterface->DatabaseConnection->prepare(
  619. "INSERT INTO settings_pacs VALUES(0, :data, :fk_physician, NULL)"
  620. );
  621. unset($data['data']['PACSID']);
  622. $data = json_encode($data['data'], JSON_NUMERIC_CHECK);
  623. $statement->bindParam(':data', $data);
  624. $statement->bindParam(':fk_physician', $fk_physician);
  625. // Error check
  626. if(!$statement->execute()) {
  627. return ['result' => 'ERROR', 'reason' => 'internal_error', 'message' => 'Database error', 'data' => $statement->errorInfo()];
  628. }
  629. }
  630. // update
  631. else {
  632. $statement = $this->DataInterface->DatabaseConnection->prepare(
  633. "UPDATE settings_pacs SET data=:data, fk_physician=:fk_physician WHERE ID = ".$data['data']['PACSID']
  634. );
  635. unset($data['data']['PACSID']);
  636. $data = json_encode($data['data'], JSON_NUMERIC_CHECK);
  637. $statement->bindParam(':data', $data);
  638. $statement->bindParam(':fk_physician', $fk_physician);
  639. // Error check
  640. if(!$statement->execute()) {
  641. return ['result' => 'ERROR', 'reason' => 'internal_error', 'message' => 'Database error', 'data' => $statement->errorInfo()];
  642. }
  643. }
  644. // OK
  645. return array(
  646. 'result' => 'OK',
  647. 'data' => $data
  648. );
  649. }
  650. /**
  651. *
  652. */
  653. public function adminEchoPost($User, $data) {
  654. $cmdLine = 'echoscu '.$data['serverAddress'].' '.$data['queryPort'].' -v 2>&1';
  655. $output=null;
  656. $retval=null;
  657. exec($cmdLine, $output, $retval);
  658. if($retval !== 0 || count($output)<1) {
  659. return [
  660. 'result' => 'ERROR',
  661. 'cmdLine' => $cmdLine,
  662. 'output' => $output,
  663. 'retval' => $retval
  664. ];
  665. }
  666. return [
  667. 'result' => 'OK',
  668. 'output' => $output
  669. ];
  670. }
  671. /**
  672. * Post customer data : ct only
  673. */
  674. public function adminCustomerPost($User, $data) {
  675. $userID = $User->ID;
  676. // Select
  677. $statement = $this->DataInterface->DatabaseConnection->prepare(
  678. "SELECT ID, email, password FROM user WHERE type = 'cro' ORDER BY ID LIMIT 0, 1"
  679. );
  680. // Error check
  681. if(!$statement->execute()) {
  682. return ['result' => 'ERROR', 'reason' => 'internal_error', 'message' => 'Database error', 'data' => $statement->errorInfo()];
  683. }
  684. $knownData = $statement->fetchAll(\PDO::FETCH_ASSOC)[0];
  685. $fk_user = $knownData['ID'];
  686. $password = $knownData['password'];
  687. $newUser = 0;
  688. if($knownData['email']!=$data['user']['email']) {
  689. $password = \Tools\UUID::v4();
  690. $newUser = 1;
  691. }
  692. // Update
  693. $statement = $this->DataInterface->DatabaseConnection->prepare(
  694. "UPDATE user SET firstname = :firstname, lastname = :lastname, password = :password, email = :email, phone = :phone WHERE ID = :ID"
  695. );
  696. $statement->bindParam(':firstname', $data['user']['firstname']);
  697. $statement->bindParam(':lastname', $data['user']['lastname']);
  698. $statement->bindParam(':password', $password);
  699. $statement->bindParam(':email', $data['user']['email']);
  700. $statement->bindParam(':phone', $data['user']['phone']);
  701. $statement->bindParam(':ID', $fk_user);
  702. // Error check
  703. if(!$statement->execute()) {
  704. return ['result' => 'ERROR', 'reason' => 'internal_error', 'message' => 'Database error', 'data' => $statement->errorInfo()];
  705. }
  706. /*
  707. // Insert user
  708. $statement = $this->DataInterface->DatabaseConnection->prepare(
  709. "INSERT INTO user(activation_token, activation_expire, password, firstname, lastname, email, phone, type) VALUES(:activation_token, :activation_expire, :password, :firstname, :lastname, :email, :phone, 'cro')"
  710. );
  711. $activation_token = \Tools\UUID::v4();
  712. $activation_expire = date('Y-m-d H:i:s', strtotime(date('Y-m-d H:i:s'). ' + 1 days'));
  713. $statement->bindParam(':activation_token', $activation_token);
  714. $statement->bindParam(':activation_expire', $activation_expire);
  715. $password = \Tools\Crypto::getHashPassword('SUPER_SECURE_DEFAULT_PASSWORD');
  716. $statement->bindParam(':password', $password);
  717. $statement->bindParam(':firstname', $data['user']['firstname']);
  718. $statement->bindParam(':lastname', $data['user']['lastname']);
  719. $statement->bindParam(':email', $data['user']['email']);
  720. $statement->bindParam(':phone', $data['user']['phone']);
  721. // Error check
  722. if(!$statement->execute()) {
  723. return ['result' => 'ERROR', 'reason' => 'internal_error', 'message' => 'Database error', 'data' => $statement->errorInfo()];
  724. }
  725. $fk_user = $this->DataInterface->DatabaseConnection->lastInsertId();
  726. */
  727. // OK
  728. return [
  729. 'result' => 'OK',
  730. 'data' => $data,
  731. 'emailTo' => $data['user']['email'],
  732. 'emailFrom' => $User->email,
  733. 'password_token' => $password,
  734. 'newUser' => $newUser
  735. ];
  736. }
  737. }
  738. }