Total Complexity | 70 |
Total Lines | 589 |
Duplicated Lines | 0 % |
Changes | 1 | ||
Bugs | 0 | Features | 0 |
Complex classes like ScheduledAnnouncement often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use ScheduledAnnouncement, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
20 | class ScheduledAnnouncement extends Model |
||
21 | { |
||
22 | public $table; |
||
23 | public $columns = ['id', 'subject', 'message', 'date', 'sent', 'session_id']; |
||
24 | |||
25 | /** |
||
26 | * Constructor. |
||
27 | */ |
||
28 | public function __construct() |
||
32 | } |
||
33 | |||
34 | /** |
||
35 | * @param array $where_conditions |
||
36 | * |
||
37 | * @return array |
||
38 | */ |
||
39 | public function get_all($where_conditions = []) |
||
40 | { |
||
41 | return Database::select( |
||
42 | '*', |
||
43 | $this->table, |
||
44 | ['where' => $where_conditions, 'order' => 'subject ASC'] |
||
45 | ); |
||
46 | } |
||
47 | |||
48 | /** |
||
49 | * @return mixed |
||
50 | */ |
||
51 | public function get_count() |
||
52 | { |
||
53 | $row = Database::select( |
||
54 | 'count(*) as count', |
||
55 | $this->table, |
||
56 | [], |
||
57 | 'first' |
||
58 | ); |
||
59 | |||
60 | return $row['count']; |
||
61 | } |
||
62 | |||
63 | /** |
||
64 | * Displays the title + grid. |
||
65 | * |
||
66 | * @param int $sessionId |
||
67 | * |
||
68 | * @return string |
||
69 | */ |
||
70 | public function getGrid($sessionId) |
||
93 | } |
||
94 | |||
95 | /** |
||
96 | * Returns a Form validator Obj. |
||
97 | * |
||
98 | * @param int $id |
||
99 | * @param string $url |
||
100 | * @param string $action add, edit |
||
101 | * @param array $sessionInfo |
||
102 | * |
||
103 | * @return FormValidator form validator obj |
||
104 | */ |
||
105 | public function returnSimpleForm($id, $url, $action, $sessionInfo = []) |
||
106 | { |
||
107 | $form = new FormValidator( |
||
108 | 'announcement', |
||
109 | 'post', |
||
110 | $url |
||
111 | ); |
||
112 | |||
113 | $form->addHidden('session_id', $sessionInfo['id']); |
||
114 | $form->addDateTimePicker('date', get_lang('Date')); |
||
115 | |||
116 | $useBaseProgress = api_get_configuration_value('scheduled_announcements_use_base_progress'); |
||
117 | if ($useBaseProgress) { |
||
118 | $extraFieldValue = new ExtraFieldValue('scheduled_announcement'); |
||
119 | $baseProgress = $extraFieldValue->get_values_by_handler_and_field_variable( |
||
120 | $id, |
||
121 | 'use_base_progress' |
||
122 | ); |
||
123 | $form->addNumeric ('progress', |
||
124 | get_lang('Progress'), |
||
125 | [ |
||
126 | 'step' => 1, |
||
127 | 'min' => 1, |
||
128 | 'max' => 100, |
||
129 | 'value' => $baseProgress['value'], |
||
130 | ], |
||
131 | true |
||
132 | ); |
||
133 | } |
||
134 | |||
135 | $form->addText('subject', get_lang('Subject')); |
||
136 | $form->addHtmlEditor('message', get_lang('Message')); |
||
137 | |||
138 | $extraField = new ExtraField('scheduled_announcement'); |
||
139 | $extra = $extraField->addElements($form, $id); |
||
140 | $js = $extra['jquery_ready_content']; |
||
141 | $form->addHtml("<script> $(function() { $js }); </script> "); |
||
142 | |||
143 | $this->setTagsInForm($form); |
||
144 | |||
145 | $form->addCheckBox('sent', null, get_lang('MessageSent')); |
||
146 | |||
147 | if ('edit' === $action) { |
||
148 | $form->addButtonUpdate(get_lang('Modify')); |
||
149 | } |
||
150 | |||
151 | return $form; |
||
152 | } |
||
153 | |||
154 | /** |
||
155 | * Returns a Form validator Obj. |
||
156 | * |
||
157 | * @todo the form should be auto generated |
||
158 | * |
||
159 | * @param string $url |
||
160 | * @param string $action add, edit |
||
161 | * @param array |
||
162 | * |
||
163 | * @return FormValidator form validator obj |
||
164 | */ |
||
165 | public function returnForm($url, $action, $sessionInfo = []) |
||
166 | { |
||
167 | // Setting the form elements |
||
168 | $header = get_lang('Add'); |
||
169 | |||
170 | if ('edit' === $action) { |
||
171 | $header = get_lang('Modify'); |
||
172 | } |
||
173 | |||
174 | $form = new FormValidator( |
||
175 | 'announcement', |
||
176 | 'post', |
||
177 | $url |
||
178 | ); |
||
179 | |||
180 | $form->addHeader($header); |
||
181 | if ('add' === $action) { |
||
182 | $form->addHtml( |
||
183 | Display::return_message( |
||
184 | nl2br(get_lang('ScheduleAnnouncementDescription')), |
||
185 | 'normal', |
||
186 | false |
||
187 | ) |
||
188 | ); |
||
189 | } |
||
190 | $form->addHidden('session_id', $sessionInfo['id']); |
||
191 | |||
192 | $useBaseDate = false; |
||
193 | $startDate = $sessionInfo['access_start_date']; |
||
194 | $endDate = $sessionInfo['access_end_date']; |
||
195 | |||
196 | if (!empty($startDate) || !empty($endDate)) { |
||
197 | $useBaseDate = true; |
||
198 | } |
||
199 | |||
200 | $typeOptions = [ |
||
201 | 'specific_date' => get_lang('SpecificDate'), |
||
202 | ]; |
||
203 | |||
204 | if ($useBaseDate) { |
||
205 | $typeOptions['base_date'] = get_lang('BaseDate'); |
||
206 | } |
||
207 | |||
208 | $useBaseProgress = api_get_configuration_value('scheduled_announcements_use_base_progress'); |
||
209 | if ($useBaseProgress) { |
||
210 | $typeOptions['base_progress'] = get_lang('BaseProgress'); |
||
211 | } |
||
212 | |||
213 | $form->addSelect( |
||
214 | 'type', |
||
215 | get_lang('Type'), |
||
216 | $typeOptions, |
||
217 | [ |
||
218 | 'onchange' => "javascript: |
||
219 | if (this.options[this.selectedIndex].value == 'base_date') { |
||
220 | document.getElementById('options').style.display = 'block'; |
||
221 | document.getElementById('specific_date').style.display = 'none'; |
||
222 | document.getElementById('base_progress').style.display = 'none'; |
||
223 | } else if (this.options[this.selectedIndex].value == 'specific_date') { |
||
224 | document.getElementById('options').style.display = 'none'; |
||
225 | document.getElementById('specific_date').style.display = 'block'; |
||
226 | document.getElementById('base_progress').style.display = 'none'; |
||
227 | } else { |
||
228 | document.getElementById('options').style.display = 'block'; |
||
229 | document.getElementById('specific_date').style.display = 'none'; |
||
230 | document.getElementById('base_progress').style.display = 'block'; |
||
231 | } |
||
232 | ", ] |
||
233 | ); |
||
234 | |||
235 | $form->addHtml('<div id="specific_date">'); |
||
236 | $form->addDateTimePicker('date', get_lang('Date')); |
||
237 | $form->addHtml('</div>'); |
||
238 | |||
239 | $form->addHtml('<div id="base_progress" style="display:none">'); |
||
240 | $form->addNumeric ('progress', |
||
241 | get_lang('Progress'), |
||
242 | [ |
||
243 | 'step' => 1, |
||
244 | 'min' => 1, |
||
245 | 'max' => 100, |
||
246 | 'value' => 100, |
||
247 | ], |
||
248 | true |
||
249 | ); |
||
250 | $form->addHtml('</div>'); |
||
251 | |||
252 | $form->addHtml('<div id="options" style="display:none">'); |
||
253 | |||
254 | $startDate = $sessionInfo['access_start_date']; |
||
255 | $endDate = $sessionInfo['access_end_date']; |
||
256 | |||
257 | $form->addText( |
||
258 | 'days', |
||
259 | get_lang('Days'), |
||
260 | false |
||
261 | ); |
||
262 | |||
263 | $form->addSelect( |
||
264 | 'moment_type', |
||
265 | get_lang('AfterOrBefore'), |
||
266 | [ |
||
267 | 'after' => get_lang('After'), |
||
268 | 'before' => get_lang('Before'), |
||
269 | ] |
||
270 | ); |
||
271 | |||
272 | if (!empty($startDate)) { |
||
273 | $options['start_date'] = get_lang('StartDate').' - '.$startDate; |
||
274 | } |
||
275 | |||
276 | if (!empty($endDate)) { |
||
277 | $options['end_date'] = get_lang('EndDate').' - '.$endDate; |
||
278 | } |
||
279 | if (!empty($options)) { |
||
280 | $form->addSelect('base_date', get_lang('BaseDate'), $options); |
||
281 | } |
||
282 | |||
283 | $form->addHtml('</div>'); |
||
284 | $form->addText('subject', get_lang('Subject')); |
||
285 | $form->addHtmlEditor('message', get_lang('Message')); |
||
286 | |||
287 | $extraField = new ExtraField('scheduled_announcement'); |
||
288 | $extra = $extraField->addElements($form); |
||
289 | $js = $extra['jquery_ready_content']; |
||
290 | $form->addHtml("<script> $(function() { $js }); </script> "); |
||
291 | |||
292 | $this->setTagsInForm($form); |
||
293 | |||
294 | if ('edit' === $action) { |
||
295 | $form->addButtonUpdate(get_lang('Modify')); |
||
296 | } else { |
||
297 | $form->addButtonCreate(get_lang('Add')); |
||
298 | } |
||
299 | |||
300 | return $form; |
||
301 | } |
||
302 | |||
303 | /** |
||
304 | * @param int $id |
||
305 | * |
||
306 | * @return string |
||
307 | */ |
||
308 | public function getAttachmentToString($id) |
||
309 | { |
||
310 | $file = $this->getAttachment($id); |
||
311 | if (!empty($file) && !empty($file['value'])) { |
||
312 | $url = api_get_path(WEB_UPLOAD_PATH).$file['value']; |
||
313 | |||
314 | return get_lang('Attachment').': '.Display::url(basename($file['value']), $url, ['target' => '_blank']); |
||
315 | } |
||
316 | |||
317 | return ''; |
||
318 | } |
||
319 | |||
320 | /** |
||
321 | * @param int $id |
||
322 | * |
||
323 | * @return array |
||
324 | */ |
||
325 | public function getAttachment($id) |
||
326 | { |
||
327 | $extraFieldValue = new ExtraFieldValue('scheduled_announcement'); |
||
328 | $attachment = $extraFieldValue->get_values_by_handler_and_field_variable($id, 'attachment'); |
||
329 | |||
330 | return $attachment; |
||
331 | } |
||
332 | |||
333 | /** |
||
334 | * @param int $urlId |
||
335 | * |
||
336 | * @return int |
||
337 | */ |
||
338 | public function sendPendingMessages($urlId = 0) |
||
339 | { |
||
340 | if (!$this->allowed()) { |
||
341 | return 0; |
||
342 | } |
||
343 | |||
344 | $messagesSent = 0; |
||
345 | $now = api_get_utc_datetime(); |
||
346 | $result = $this->get_all(); |
||
347 | $extraFieldValue = new ExtraFieldValue('scheduled_announcement'); |
||
348 | |||
349 | // get user extra fields list (only visible to self and filter-able) |
||
350 | $extraField = new ExtraField('user'); |
||
351 | $extraFields = $extraField->get_all(['filter = ? AND visible_to_self = ?' => [1, 1]]); |
||
352 | |||
353 | foreach ($result as $result) { |
||
354 | if (empty($result['sent'])) { |
||
355 | if (!empty($result['date']) && $result['date'] < $now) { |
||
356 | $sessionId = $result['session_id']; |
||
357 | $sessionInfo = api_get_session_info($sessionId); |
||
358 | if (empty($sessionInfo)) { |
||
359 | continue; |
||
360 | } |
||
361 | $users = SessionManager::get_users_by_session( |
||
362 | $sessionId, |
||
363 | 0, |
||
364 | false, |
||
365 | $urlId |
||
366 | ); |
||
367 | |||
368 | $coachId = $sessionInfo['id_coach']; |
||
369 | |||
370 | if (empty($users) || empty($coachId)) { |
||
371 | continue; |
||
372 | } |
||
373 | |||
374 | $coachList = []; |
||
375 | if ($users) { |
||
376 | $sendToCoaches = $extraFieldValue->get_values_by_handler_and_field_variable( |
||
377 | $result['id'], |
||
378 | 'send_to_coaches' |
||
379 | ); |
||
380 | $courseList = SessionManager::getCoursesInSession($sessionId); |
||
381 | if (!empty($sendToCoaches) && !empty($sendToCoaches['value']) && 1 == $sendToCoaches['value']) { |
||
382 | foreach ($courseList as $courseItemId) { |
||
383 | $coaches = SessionManager::getCoachesByCourseSession( |
||
384 | $sessionId, |
||
385 | $courseItemId |
||
386 | ); |
||
387 | $coachList = array_merge($coachList, $coaches); |
||
388 | } |
||
389 | $coachList = array_unique($coachList); |
||
390 | } |
||
391 | |||
392 | $useBaseProgress = api_get_configuration_value('scheduled_announcements_use_base_progress'); |
||
393 | if ($useBaseProgress) { |
||
394 | $baseProgress = $extraFieldValue->get_values_by_handler_and_field_variable( |
||
395 | $result['id'], |
||
396 | 'use_base_progress' |
||
397 | ); |
||
398 | if (empty($baseProgress) || empty($baseProgress['value']) || $baseProgress['value'] < 1) { |
||
399 | $this->update(['id' => $result['id'], 'sent' => 1]); |
||
400 | } |
||
401 | } else { |
||
402 | $this->update(['id' => $result['id'], 'sent' => 1]); |
||
403 | } |
||
404 | |||
405 | $attachments = $this->getAttachmentToString($result['id']); |
||
406 | $subject = $result['subject']; |
||
407 | |||
408 | $courseInfo = []; |
||
409 | if (!empty($courseList)) { |
||
410 | $courseId = current($courseList); |
||
411 | $courseInfo = api_get_course_info_by_id($courseId); |
||
412 | } |
||
413 | |||
414 | $message = ''; |
||
415 | foreach ($users as $user) { |
||
416 | // Take original message |
||
417 | $message = $result['message']; |
||
418 | $userInfo = api_get_user_info($user['user_id']); |
||
419 | $userPicture = UserManager::getUserPicture($user['user_id'], USER_IMAGE_SIZE_ORIGINAL); |
||
420 | |||
421 | $progress = ''; |
||
422 | if (!empty($sessionInfo) && !empty($courseInfo)) { |
||
423 | $progress = Tracking::get_avg_student_progress( |
||
424 | $user['user_id'], |
||
425 | $courseInfo['code'], |
||
426 | [], |
||
427 | $sessionId |
||
428 | ); |
||
429 | } |
||
430 | |||
431 | if ($useBaseProgress) { |
||
432 | $baseProgress = $extraFieldValue->get_values_by_handler_and_field_variable( |
||
433 | $result['id'], |
||
434 | 'use_base_progress' |
||
435 | ); |
||
436 | if (!empty($baseProgress) && !empty($baseProgress['value']) && $baseProgress['value'] >= 1) { |
||
437 | if ((is_numeric($progress) && $progress > $baseProgress['value']) || !is_numeric($progress)) { |
||
438 | continue; |
||
439 | } else { |
||
440 | $comment = json_decode($baseProgress['comment'], true); |
||
441 | if ($comment !== null && is_array($comment)) { |
||
442 | if (isset($comment['sended']) && is_array($comment['sended'])) { |
||
443 | $userFound = false; |
||
444 | foreach ($comment['sended'] as $item) { |
||
445 | if (isset($item['user']) && $item['user'] === $user['user_id']) { |
||
446 | $userFound = true; |
||
447 | break; |
||
448 | } |
||
449 | } |
||
450 | if ($userFound) { |
||
451 | continue; |
||
452 | } else { |
||
453 | $comment['sended'][] = ['user' => $user['user_id'], 'send_date' => time(), 'progress_user' => $progress, 'progress_mark' => $baseProgress['value']]; |
||
454 | $newExtraFieldParams = $baseProgress; |
||
455 | $newExtraFieldParams['comment'] = json_encode($comment); |
||
456 | $extraFieldValue->save($newExtraFieldParams); |
||
457 | } |
||
458 | } |
||
459 | } else { |
||
460 | $comment['sended'][] = ['user' => $user['user_id'], 'send_date' => time(), 'progress_user' => $progress, 'progress_mark' => $baseProgress['value']]; |
||
461 | $newExtraFieldParams = $baseProgress; |
||
462 | $newExtraFieldParams['comment'] = json_encode($comment); |
||
463 | $extraFieldValue->save($newExtraFieldParams); |
||
464 | } |
||
465 | } |
||
466 | } |
||
467 | } |
||
468 | |||
469 | if (is_numeric($progress)) { |
||
470 | $progress = $progress.'%'; |
||
471 | } else { |
||
472 | $progress = '0%'; |
||
473 | } |
||
474 | |||
475 | $startTime = api_get_local_time( |
||
476 | $sessionInfo['access_start_date'], |
||
477 | null, |
||
478 | null, |
||
479 | true |
||
480 | ); |
||
481 | $endTime = api_get_local_time( |
||
482 | $sessionInfo['access_end_date'], |
||
483 | null, |
||
484 | null, |
||
485 | true |
||
486 | ); |
||
487 | |||
488 | $generalCoach = ''; |
||
489 | $generalCoachEmail = ''; |
||
490 | if (!empty($coachId)) { |
||
491 | $coachInfo = api_get_user_info($coachId); |
||
492 | if (!empty($coachInfo)) { |
||
493 | $generalCoach = $coachInfo['complete_name']; |
||
494 | $generalCoachEmail = $coachInfo['email']; |
||
495 | } |
||
496 | } |
||
497 | |||
498 | $tags = [ |
||
499 | '((session_name))' => $sessionInfo['name'], |
||
500 | '((session_start_date))' => $startTime, |
||
501 | '((general_coach))' => $generalCoach, |
||
502 | '((general_coach_email))' => $generalCoachEmail, |
||
503 | '((session_end_date))' => $endTime, |
||
504 | '((user_username))' => $userInfo['username'], |
||
505 | '((user_complete_name))' => $userInfo['complete_name'], |
||
506 | '((user_firstname))' => $userInfo['firstname'], |
||
507 | '((user_lastname))' => $userInfo['lastname'], |
||
508 | '((user_first_name))' => $userInfo['firstname'], |
||
509 | '((user_last_name))' => $userInfo['lastname'], |
||
510 | '((user_official_code))' => $userInfo['official_code'], |
||
511 | '((user_picture))' => $userPicture, |
||
512 | '((lp_progress))' => $progress, |
||
513 | ]; |
||
514 | |||
515 | if (!empty($extraFields)) { |
||
516 | $efv = new ExtraFieldValue('user'); |
||
517 | |||
518 | foreach ($extraFields as $extraField) { |
||
519 | $valueExtra = $efv->get_values_by_handler_and_field_variable( |
||
520 | $user['user_id'], |
||
521 | $extraField['variable'], |
||
522 | true |
||
523 | ); |
||
524 | $tags['(('.strtolower($extraField['variable']).'))'] = $valueExtra['value']; |
||
525 | } |
||
526 | } |
||
527 | |||
528 | $message = str_replace(array_keys($tags), $tags, $message); |
||
529 | $message .= $attachments; |
||
530 | |||
531 | MessageManager::send_message_simple( |
||
532 | $userInfo['user_id'], |
||
533 | $subject, |
||
534 | $message, |
||
535 | $coachId |
||
536 | ); |
||
537 | } |
||
538 | |||
539 | $message = get_lang('YouAreReceivingACopyBecauseYouAreACourseCoach').'<br /><br />'.$message; |
||
540 | |||
541 | foreach ($coachList as $courseCoachId) { |
||
542 | MessageManager::send_message_simple( |
||
543 | $courseCoachId, |
||
544 | get_lang('YouAreReceivingACopyBecauseYouAreACourseCoach').' '.$subject, |
||
545 | $message, |
||
546 | $coachId |
||
547 | ); |
||
548 | } |
||
549 | } |
||
550 | |||
551 | $messagesSent++; |
||
552 | } |
||
553 | } |
||
554 | } |
||
555 | |||
556 | return $messagesSent; |
||
557 | } |
||
558 | |||
559 | /** |
||
560 | * @return array |
||
561 | */ |
||
562 | public function getTags() |
||
563 | { |
||
564 | $tags = [ |
||
565 | '((session_name))', |
||
566 | '((session_start_date))', |
||
567 | '((session_end_date))', |
||
568 | '((general_coach))', |
||
569 | '((general_coach_email))', |
||
570 | '((user_username))', |
||
571 | '((user_complete_name))', |
||
572 | '((user_first_name))', |
||
573 | '((user_last_name))', |
||
574 | '((user_picture))', |
||
575 | '((lp_progress))', |
||
576 | '((user_official_code))', |
||
577 | ]; |
||
578 | // get user extra fields list (only visible to self and filter-able) |
||
579 | $extraField = new ExtraField('user'); |
||
580 | $extraFields = $extraField->get_all(['filter = ? AND visible_to_self = ?' => [1, 1]]); |
||
581 | if (!empty($extraFields)) { |
||
582 | foreach ($extraFields as $extraField) { |
||
583 | $tags[] = '(('.strtolower($extraField['variable']).'))'; |
||
584 | } |
||
585 | } |
||
586 | |||
587 | return $tags; |
||
588 | } |
||
589 | |||
590 | /** |
||
591 | * @return bool |
||
592 | */ |
||
593 | public function allowed() |
||
596 | } |
||
597 | |||
598 | /** |
||
599 | * @param FormValidator $form |
||
600 | */ |
||
601 | private function setTagsInForm(&$form) |
||
602 | { |
||
613 |