Passed
Push — dev ( 8b110b...eba5ae )
by Salim
03:53
created

Form_Processor::getExistingFormData()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 0
dl 0
loc 5
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 Copyright (C) 2018-2020 KANOUN Salim
4
 This program is free software; you can redistribute it and/or modify
5
 it under the terms of the Affero GNU General Public v.3 License as published by
6
 the Free Software Foundation;
7
 This program is distributed in the hope that it will be useful,
8
 but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
 Affero GNU General Public Public for more details.
11
 You should have received a copy of the Affero GNU General Public Public along
12
 with this program; if not, write to the Free Software Foundation, Inc.,
13
 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
14
 */
15
16
/**
17
 * Abstract class to handle review in the system
18
 * Each Study-Visit should extend this abstract class and redifine the two abstract methods
19
 * - saveSpecificForm : Which recieve the raw form and should write data to the specific table of database
20
 * - setVisitValidation : Which should define the rules to change status of review's visit (ex : Wait Adjudication or Done)
21
 * 
22
 * These two methodes will be launched for each new review recieved by the system
23
 * 
24
 * The makeReviewUnavailable() can be overrided to let the visit available for review even if Review status "Done" is reached 
25
 * (by default it will no longer accept new review after reaching this status)
26
 * @author salim
27
 *
28
 */
29
30
abstract class Form_Processor {
31
	
32
	protected $linkpdo;
33
	protected $visitObject;
34
	protected $study;
35
	protected $id_visit;
36
	protected $specificTable;
37
	protected $local;
38
	private $username;
39
	protected $reviewStatus;
40
	protected $reviewAvailable;
41
	public $reviewObject;
42
	protected $rawDataForm;
43
	
44
	function __construct(Visit $visitObject, bool $local, string $username, PDO $linkpdo) {
45
		$this->linkpdo=$linkpdo;
46
		$this->local=$local;
47
		$this->username=$username;
48
		
49
		$this->visitObject=$visitObject;
50
		$this->id_visit=$visitObject->id_visit;
51
		$visitCharacteristics=$visitObject->getVisitCharacteristics();
52
		
53
		//Store the table specific name and the current study
54
		$this->specificTable=$visitCharacteristics->tableReviewSpecificName;
55
		$this->study=$visitObject->study;
56
		//Store the review status
57
		$this->reviewStatus=$visitObject->reviewStatus;
58
		$this->reviewAvailable=$visitObject->reviewAvailable;
59
60
		$this->loadSavedForm();
61
	}
62
	
63
	/**
64
	 * Save the  form in the specific table as specified in the child dedicated objet who will extend this class
65
	 * @param $data :Post data from the dedicated from
0 ignored issues
show
Documentation Bug introduced by
The doc comment :Post at position 0 could not be parsed: Unknown type name ':' at position 0 in :Post.
Loading history...
66
	 * @param $id_Review : current Id review
67
	 * @param $specificTable : name of the specific table for the study-visit
68
	 * @param $update : if review already exists (draft), value is true (if true make update, if false make insert)
69
	 */
70
	abstract protected function saveSpecificForm($data, $id_review, $update);
71
	
72
	/**
73
	 * Set the visit status after review (Not Done, adjudication, Done), need to be redifined in the child object
74
	 */
75
	abstract public function setVisitValidation();
76
	
77
	/*
78
	 * Create new entry in review table
79
	 */
80
	protected function createReview() {
81
		$this->reviewObject=Review::createReview($this->id_visit, $this->username, $this->local,
82
			($this->reviewStatus == Visit::REVIEW_WAIT_ADJUDICATION), $this->linkpdo);
83
	}
84
	
85
	/**
86
	 * Set review status as draft (validate = false) or validated (validate=true)
87
	 * This methods is triggered by the system at form submission and call the save specific form
88
	 * to define which value need to be written in the specific table
89
	 */
90
	public function saveForm($data, bool $validate) {
91
	    
92
		$this->rawDataForm=$data;
93
	    
94
		//If reviewer check that review is available before saving process
95
		if (!$this->local && !$this->reviewAvailable) {
96
			return;
97
		}
98
		
99
		//Get saved form, return either local form or reviewer's users form if exist
100
		//or null if not existing
101
		
102
		if (empty($this->reviewObject)) {
103
			$this->createReview();
104
			$update=false;       
105
		}else {
106
			$update=true;
107
			//If already existing validated review, exit without modifying anything
108
			if ($this->reviewObject->validated) {
109
				return;
110
			}
111
	       
112
		}
113
	    
114
		//Call the child redifined save specific form to save the specific data of the form
115
		try {
116
			$this->saveSpecificForm($data, $this->reviewObject->id_review, $update);
117
		}catch (Exception $e) {
118
			error_log($e->getMessage());
119
			if (!$update) {
120
				$this->reviewObject->hardDeleteReview();
121
			}
122
			throw new Exception("Error during save");
123
		}
124
125
		if($update){
126
			$this->reviewObject->updateReviewDate();
127
		}
128
		
129
		if ($validate) {
130
			$this->reviewObject->changeReviewValidationStatus($validate);
131
		}
132
		//update the visit status if we are processing a local form
133
		if ($this->local) {
134
			if ($validate) {
135
				$this->visitObject->changeVisitStateInvestigatorForm(Visit::LOCAL_FORM_DONE);
136
			}else {
137
				$this->visitObject->changeVisitStateInvestigatorForm(Visit::LOCAL_FORM_DRAFT);
138
			}
139
		}
140
		
141
		//Log Activity
142
		if ($this->local) {
143
			$role="Investigator";
144
		}else {
145
			$role="Reviewer";
146
		}
147
		$actionDetails['patient_code']=$this->visitObject->patientCode;
0 ignored issues
show
Comprehensibility Best Practice introduced by
$actionDetails was never initialized. Although not strictly required by PHP, it is generally a good practice to add $actionDetails = array(); before regardless.
Loading history...
148
		$actionDetails['type_visit']=$this->visitObject->visitType;
149
		$actionDetails['modality_visit']=$this->visitObject->visitGroupObject->groupModality;
150
		$actionDetails['id_review']=$this->reviewObject->id_review;
151
		$actionDetails['associated_files']=$this->reviewObject->associatedFiles;
152
		$actionDetails['local_review']=intval($this->local);
153
		$actionDetails['adjudication']=intval($this->reviewStatus == Visit::REVIEW_WAIT_ADJUDICATION);
154
		$actionDetails['create']=!$update;
155
		$actionDetails['raw_data']=$data;
156
		
157
		Tracker::logActivity($this->username, $role, $this->study, $this->id_visit, "Save Form", $actionDetails);
158
		
159
		//If central review still not at "Done" status Check if validation is reached
160
		if ($validate && !$this->local && $this->reviewStatus != Visit::REVIEW_DONE) {
161
			$this->setVisitValidation();
162
		}
163
		
164
	}
165
	
166
	/**
167
	 * update the review conclusion of the visit, pass decision in argument
168
	 * and trigger the review availability decision method
169
	 * @param $reviewConclusion : constant value from this clas
0 ignored issues
show
Documentation Bug introduced by
The doc comment : constant at position 0 could not be parsed: Unknown type name ':' at position 0 in : constant.
Loading history...
170
	 * @param string $reviewStatus
171
	 * @param $conclusionValue
172
	 */
173
	protected function changeVisitValidationStatus(string $reviewStatus, $conclusionValue="N/A") {
174
		$this->visitObject->changeVisitValidationStatus($reviewStatus, $conclusionValue);
175
		$this->reviewAvailabilityDecision($reviewStatus);
176
177
		//Send Notification emails
178
		if ($reviewStatus == Visit::REVIEW_WAIT_ADJUDICATION) {
179
180
			$email=new Send_Email($this->linkpdo);
181
			//SK A AMELIORER POUR EVITER DE MAILIER LES REVIEWER QUI ONT DEJA REPONDU
182
			//NECESSITE DE FILTER LA LISTE DES REVIEWERS DE L ETUDE
183
			$email->addGroupEmails($this->visitObject->study, User::REVIEWER)
184
					->addGroupEmails($this->visitObject->study, User::SUPERVISOR);
185
			$email->sendAwaitingAdjudicationMessage($this->visitObject->study, $this->visitObject->patientCode, $this->visitObject->visitType);
186
187
		}else if ($reviewStatus == Visit::REVIEW_DONE) {
188
189
			$email=new Send_Email($this->linkpdo);
190
			$uploaderUserObject=new User($this->visitObject->uploaderUsername, $this->linkpdo);
191
			$uploaderEmail=$uploaderUserObject->userEmail;
192
			$email->addGroupEmails($this->visitObject->study, User::MONITOR)
193
					->addGroupEmails($this->visitObject->study, User::SUPERVISOR)
194
					->addEmail($uploaderEmail);
195
			$email->sendVisitConcludedMessage($this->visitObject->study, $this->visitObject->patientCode, $this->visitObject->visitType, $conclusionValue);
196
197
		}
198
	}
199
	
200
	/**
201
	 * Return the saved form of the current user.
202
	 * Used to fill the form at display
203
	 * @return array of the general and specific table
204
	 */
205
	public function loadSavedForm() {
206
		try {
207
			if ($this->local) {
208
				$this->reviewObject=$this->visitObject->getReviewsObject(true);
209
			}else {
210
				$this->reviewObject=$this->visitObject->queryExistingReviewForReviewer($this->username);
211
			}
212
213
		}catch (Exception $e) { }
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
214
	    
215
		return $this->reviewObject;
216
		
217
	}
218
	
219
	/**
220
	 * return all reviews (local and reviewer) of the current visit
221
	 * Usefull to determine visit conclusion status
222
	 */
223
	public function getAllValidatedFormsOfVisit() {
224
	    
225
		$query=$this->linkpdo->prepare('SELECT * FROM reviews,'.$this->specificTable.' WHERE reviews.id_review='.$this->specificTable.'.id_review AND reviews.id_visit=:idVisit AND reviews.validated=1 AND reviews.deleted=0');
226
		$query->execute(array(
227
			'idVisit'=>$this->id_visit
228
		));
229
		$datas=$query->fetchAll(PDO::FETCH_ASSOC);
230
		return $datas;
231
	}
232
233
	/**
234
	 * Return of validated review object (no local form)
235
	 */
236
	public function getValidatedReviewObjects() : array {
237
		$reviewsObject=$this->visitObject->getReviewsObject(false);
238
		//Filter only validated review that will be analyzed
239
		$validatedReviewObjects=array_filter($reviewsObject, function($review) {
240
			if ($review->validated) {
241
				return true;
242
			}else {
243
				return false;
244
			}
245
		});
246
		//Reindex results from index zero
247
		$validatedReviewObjects=array_values($validatedReviewObjects);
248
249
		return $validatedReviewObjects;
250
	}
251
	
252
	/**
253
	 * Get existing form for current user
254
	 * can be overrided to add additional data such as investigator form data
255
	 */
256
	public function getExistingFormData() {
257
		if( ! empty($this->reviewObject)){
258
			return ($this->reviewObject->getSpecificData());
259
		}else{
260
			return [];
261
		}
262
		
263
	}
264
	
265
	/**
266
	 * When Review conclusion "Done" reached Will make review unavailable for new review
267
	 * Can be overided if needed different condition
268
	 * @param string $reviewConclusion
269
	 */
270
	protected function reviewAvailabilityDecision(string $reviewConclusion) {
271
		//If Done reached make the review unavailable for review
272
		if ($reviewConclusion == Visit::REVIEW_DONE) {
273
			$this->visitObject->changeReviewAvailability(false);
274
		}
275
		//Needed in case of deletion of a review (even if true by default initialy, need to come back if deletion)
276
		else {
277
			$this->visitObject->changeReviewAvailability(true);
278
		}
279
	}
280
	
281
}