PageRenderTime 40ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/api/database/participant.class.php

https://github.com/patrickdemond/beartooth
PHP | 224 lines | 99 code | 23 blank | 102 comment | 8 complexity | 546e5d96709b5f5691887642cc746c20 MD5 | raw file
  1. <?php
  2. /**
  3. * participant.class.php
  4. *
  5. * @author Patrick Emond <emondpd@mcmaster.ca>
  6. * @filesource
  7. */
  8. namespace beartooth\database;
  9. use cenozo\lib, cenozo\log, beartooth\util;
  10. /**
  11. * participant: record
  12. */
  13. class participant extends \cenozo\database\participant
  14. {
  15. /**
  16. * Updates the participant's queue status.
  17. *
  18. * The participant's entries in the queue_has_participant table are all removed and
  19. * re-determined. This method should be called if any of the participant's details
  20. * which affect which queue they belong in change (eg: change to appointments, consent
  21. * status, state, etc).
  22. * WARNING: this operation is db-intensive so it should only be called after all
  23. * changes to the participant are complete (never more than once per operation).
  24. * @author Patrick Emond <emondpd@mcmaster.ca>
  25. * @access public
  26. */
  27. public function update_queue_status()
  28. {
  29. // check the primary key value
  30. if( is_null( $this->id ) )
  31. {
  32. log::warning( 'Tried to update queue status of participant with no id.' );
  33. return NULL;
  34. }
  35. $queue_class_name = lib::get_class_name( 'database\queue' );
  36. $queue_class_name::repopulate( $this );
  37. }
  38. /**
  39. * Get the participant's most recent, closed assignment.
  40. * @author Patrick Emond <emondpd@mcmaster.ca>
  41. * @return assignment
  42. * @access public
  43. */
  44. public function get_last_finished_assignment()
  45. {
  46. // check the primary key value
  47. if( is_null( $this->id ) )
  48. {
  49. log::warning( 'Tried to query participant with no id.' );
  50. return NULL;
  51. }
  52. $modifier = lib::create( 'database\modifier' );
  53. $modifier->where( 'interview.participant_id', '=', $this->id );
  54. $modifier->where( 'end_datetime', '!=', NULL );
  55. $modifier->order_desc( 'start_datetime' );
  56. $modifier->limit( 1 );
  57. $assignment_class_name = lib::get_class_name( 'database\assignment' );
  58. $assignment_list = $assignment_class_name::select( $modifier );
  59. return 0 == count( $assignment_list ) ? NULL : current( $assignment_list );
  60. }
  61. /**
  62. * Get the participant's current assignment (or null if none is found)
  63. * @author Patrick Emond <emondpd@mcmaster.ca>
  64. * @return assignment
  65. * @access public
  66. */
  67. public function get_current_assignment()
  68. {
  69. // check the primary key value
  70. if( is_null( $this->id ) )
  71. {
  72. log::warning( 'Tried to query participant with no id.' );
  73. return NULL;
  74. }
  75. $modifier = lib::create( 'database\modifier' );
  76. $modifier->where( 'interview.participant_id', '=', $this->id );
  77. $modifier->where( 'end_datetime', '=', NULL );
  78. $modifier->order_desc( 'start_datetime' );
  79. $modifier->limit( 1 );
  80. $assignment_class_name = lib::get_class_name( 'database\assignment' );
  81. $assignment_list = $assignment_class_name::select( $modifier );
  82. return 0 == count( $assignment_list ) ? NULL : current( $assignment_list );
  83. }
  84. /**
  85. * A convenience function to get this participant's next of kin.
  86. * This method is necessary since there is a 1 to N relationship between participant and
  87. * next_of_kin, however, the next_of_kin.participant_id column is unique.
  88. * @author Patrick Emond <emondpd@mcmaster.ca>
  89. * @return database\next_of_kin
  90. * @access public
  91. */
  92. public function get_next_of_kin()
  93. {
  94. $next_of_kin_class_name = lib::get_class_name( 'database\next_of_kin' );
  95. return $next_of_kin_class_name::get_unique_record( 'participant_id', $this->id );
  96. }
  97. /**
  98. * A convenience function to get this participant's next of kin.
  99. * This method is necessary since there is a 1 to N relationship between participant and
  100. * data_collection, however, the data_collection.participant_id column is unique.
  101. * @author Patrick Emond <emondpd@mcmaster.ca>
  102. * @return database\data_collection
  103. * @access public
  104. */
  105. public function get_data_collection()
  106. {
  107. $data_collection_class_name = lib::get_class_name( 'database\data_collection' );
  108. return $data_collection_class_name::get_unique_record( 'participant_id', $this->id );
  109. }
  110. /**
  111. * Returns the participant's effective qnaire.
  112. *
  113. * The "effective" qnaire is determined based on the participant's current interview.
  114. * If they have not yet started an interview then the first qnaire is returned.
  115. * If they current have an incomplete interview then that interview's qnaire is returned.
  116. * If their current interview is complete then the next qnaire is returned, and if there
  117. * is no next qnaire then NULL is returned (ie: the participant has completed all qnaires).
  118. * @author Patrick Emond <emondpd@mcmaster.ca>
  119. * @return database\qnaire
  120. * @access public
  121. */
  122. public function get_effective_qnaire()
  123. {
  124. $this->load_queue_data();
  125. return is_null( $this->effective_qnaire_id ) ?
  126. NULL : lib::create( 'database\qnaire', $this->effective_qnaire_id );
  127. }
  128. /**
  129. * Returns the participant's qnaire start date.
  130. *
  131. * The qnaire start date is determined based on the following rules:
  132. * If they have not yet started an interview then the date is based on the first qnaire's
  133. * delay and the start event needed to start that qnaire, or the current date if there is
  134. * no start event for the first qnaire.
  135. * If their current interview is complete then the date is based on the next qnaire's delay
  136. * and the greatest of its start event and the completed interview's completion date.
  137. * If there is no next qnaire or the current interview is not complete then NULL is returned,
  138. * meaning the qnaire has already started (ie: the start date is in the past).
  139. * @author Patrick Emond <emondpd@mcmaster.ca>
  140. * @return datetime
  141. * @access public
  142. */
  143. public function get_start_qnaire_date()
  144. {
  145. $this->load_queue_data();
  146. return is_null( $this->start_qnaire_date ) ?
  147. NULL : util::get_datetime_object( $this->start_qnaire_date );
  148. }
  149. /**
  150. * Fills in the effective qnaire id and start qnaire date
  151. * @author Patrick Emond <emondpd@mcmaster.ca>
  152. * @access private
  153. */
  154. private function load_queue_data()
  155. {
  156. if( $this->queue_data_loaded ) return;
  157. // check the primary key value
  158. if( is_null( $this->id ) )
  159. {
  160. log::warning( 'Tried to query participant with no id.' );
  161. return NULL;
  162. }
  163. $database_class_name = lib::get_class_name( 'database\database' );
  164. // the qnaire date is cached in the queue_has_participant joining table
  165. $row = static::db()->get_row( sprintf(
  166. 'SELECT * FROM queue_has_participant '.
  167. 'WHERE participant_id = %s '.
  168. 'ORDER BY queue_id DESC '.
  169. 'LIMIT 1',
  170. $database_class_name::format_string( $this->id ) ) );
  171. if( count( $row ) )
  172. {
  173. $this->effective_qnaire_id = $row['qnaire_id'];
  174. $this->start_qnaire_date = $row['start_qnaire_date'];
  175. }
  176. $this->queue_data_loaded = true;
  177. }
  178. /**
  179. * Whether the participants queue-specific data has been read from the database
  180. * @var boolean
  181. * @access private
  182. */
  183. private $queue_data_loaded = false;
  184. /**
  185. * The participant's effective questionnaire id (from a custom query)
  186. * @var int
  187. * @access private
  188. */
  189. private $effective_qnaire_id = NULL;
  190. /**
  191. * The date that the current questionnaire is to begin (from a custom query)
  192. * @var int
  193. * @access private
  194. */
  195. private $start_qnaire_date = NULL;
  196. }
  197. // define the join to the interview table
  198. $interview_mod = lib::create( 'database\modifier' );
  199. $interview_mod->where( 'participant.id', '=', 'participant_last_interview.participant_id', false );
  200. $interview_mod->where( 'participant_last_interview.interview_id', '=', 'interview.id', false );
  201. participant::customize_join( 'interview', $interview_mod );