Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like SystemAnnouncementManager 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. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
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 SystemAnnouncementManager, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
7 | class SystemAnnouncementManager |
||
8 | { |
||
9 | const VISIBLE_GUEST = 1; |
||
10 | const VISIBLE_STUDENT = 2; |
||
11 | const VISIBLE_TEACHER = 3; |
||
12 | |||
13 | /** |
||
14 | * Displays all announcements |
||
15 | * @param int $visible VISIBLE_GUEST, VISIBLE_STUDENT or VISIBLE_TEACHER |
||
16 | * @param int $id The identifier of the announcement to display |
||
17 | */ |
||
18 | public static function display_announcements($visible, $id = -1) |
||
99 | |||
100 | /** |
||
101 | * @param $visible |
||
102 | * @param $id |
||
103 | * @param int $start |
||
104 | * @param string $user_id |
||
105 | * @return string |
||
106 | */ |
||
107 | public static function display_all_announcements($visible, $id = -1, $start = 0,$user_id='') |
||
108 | { |
||
109 | $user_selected_language = api_get_interface_language(); |
||
110 | $start = intval($start); |
||
111 | $userGroup = new UserGroup(); |
||
112 | $tbl_announcement_group = Database :: get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS_GROUPS); |
||
113 | $temp_user_groups = $userGroup->get_groups_by_user(api_get_user_id(),0); |
||
114 | $groups = array(); |
||
115 | View Code Duplication | foreach ($temp_user_groups as $user_group) { |
|
116 | $groups = array_merge($groups, array($user_group['id'])); |
||
117 | $groups = array_merge($groups, $userGroup->get_parent_groups($user_group['id'])); |
||
118 | } |
||
119 | |||
120 | // Checks if tables exists to not break platform not updated |
||
121 | $groups_string = '('.implode($groups,',').')'; |
||
122 | |||
123 | $db_table = Database :: get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS); |
||
124 | $now = api_get_utc_datetime(); |
||
125 | |||
126 | $sql = "SELECT * FROM ".$db_table." |
||
127 | WHERE |
||
128 | (lang = '$user_selected_language' OR lang IS NULL) AND |
||
129 | ( '$now' >= date_start AND '$now' <= date_end) "; |
||
130 | |||
131 | View Code Duplication | switch ($visible) { |
|
132 | case self::VISIBLE_GUEST: |
||
133 | $sql .= " AND visible_guest = 1 "; |
||
134 | break; |
||
135 | case self::VISIBLE_STUDENT: |
||
136 | $sql .= " AND visible_student = 1 "; |
||
137 | break; |
||
138 | case self::VISIBLE_TEACHER: |
||
139 | $sql .= " AND visible_teacher = 1 "; |
||
140 | break; |
||
141 | } |
||
142 | |||
143 | if (count($groups) > 0) { |
||
144 | $sql .= " OR id IN ( |
||
145 | SELECT announcement_id FROM $tbl_announcement_group |
||
146 | WHERE group_id in $groups_string |
||
147 | ) "; |
||
148 | } |
||
149 | |||
150 | if (api_is_multiple_url_enabled()) { |
||
151 | $current_access_url_id = api_get_current_access_url_id(); |
||
152 | $sql .= " AND access_url_id IN ('1', '$current_access_url_id')"; |
||
153 | } |
||
154 | |||
155 | if(!isset($_GET['start']) || $_GET['start'] == 0) { |
||
156 | $sql .= " ORDER BY date_start DESC LIMIT ".$start.",20"; |
||
157 | } else { |
||
158 | $sql .= " ORDER BY date_start DESC LIMIT ".($start+1).",20"; |
||
159 | } |
||
160 | $announcements = Database::query($sql); |
||
161 | $content = ''; |
||
162 | if (Database::num_rows($announcements) > 0) { |
||
163 | $content .= '<div class="system_announcements">'; |
||
164 | $content .= '<h3>'.get_lang('SystemAnnouncements').'</h3>'; |
||
165 | $content .= '<table align="center">'; |
||
166 | $content .= '<tr>'; |
||
167 | $content .= '<td>'; |
||
168 | $content .= SystemAnnouncementManager :: display_arrow($user_id); |
||
169 | $content .= '</td>'; |
||
170 | $content .= '</tr>'; |
||
171 | $content .= '</table>'; |
||
172 | $content .= '<table align="center" border="0" width="900px">'; |
||
173 | while ($announcement = Database::fetch_object($announcements)) { |
||
174 | $display_date = api_convert_and_format_date($announcement->display_date, DATE_FORMAT_LONG); |
||
175 | $content .= '<tr><td>'; |
||
176 | $content .= '<a name="'.$announcement->id.'"></a> |
||
177 | <div class="system_announcement"> |
||
178 | <h2>'.$announcement->title.'</h2><div class="system_announcement_date">'.$display_date.'</div> |
||
179 | <br /> |
||
180 | <div class="system_announcement_content">' |
||
181 | .$announcement->content.' |
||
182 | </div> |
||
183 | </div><br />'; |
||
184 | $content .= '</tr></td>'; |
||
185 | } |
||
186 | $content .= '</table>'; |
||
187 | |||
188 | $content .= '<table align="center">'; |
||
189 | $content .= '<tr>'; |
||
190 | $content .= '<td>'; |
||
191 | $content .= SystemAnnouncementManager :: display_arrow($user_id); |
||
192 | $content .= '</td>'; |
||
193 | $content .= '</tr>'; |
||
194 | $content .= '</table>'; |
||
195 | $content .= '</div>'; |
||
196 | } |
||
197 | |||
198 | return $content; |
||
199 | } |
||
200 | |||
201 | /** |
||
202 | * @param int $user_id |
||
203 | * @return string |
||
204 | */ |
||
205 | public static function display_arrow($user_id) |
||
206 | { |
||
207 | $start = (int)$_GET['start']; |
||
208 | $nb_announcement = SystemAnnouncementManager :: count_nb_announcement($start, $user_id); |
||
209 | $next = ((int)$_GET['start']+19); |
||
210 | $prev = ((int)$_GET['start']-19); |
||
211 | $content = ''; |
||
212 | if (!isset($_GET['start']) || $_GET['start'] == 0) { |
||
213 | View Code Duplication | if ($nb_announcement > 20) { |
|
214 | $content .= '<a href="news_list.php?start='.$next.'">'.get_lang('NextBis').' >> </a>'; |
||
215 | } |
||
216 | } else { |
||
217 | echo '<a href="news_list.php?start='.$prev.'"> << '.get_lang('Prev').'</a>'; |
||
218 | View Code Duplication | if ($nb_announcement > 20) { |
|
219 | $content .= '<a href="news_list.php?start='.$next.'">'.get_lang('NextBis').' >> </a>'; |
||
220 | } |
||
221 | } |
||
222 | return $content; |
||
223 | } |
||
224 | |||
225 | /** |
||
226 | * @param int $start |
||
227 | * @param string $user_id |
||
228 | * @return int |
||
229 | */ |
||
230 | public static function count_nb_announcement($start = 0, $user_id = '') |
||
231 | { |
||
232 | $start = intval($start); |
||
233 | $visibility = api_is_allowed_to_create_course() ? self::VISIBLE_TEACHER : self::VISIBLE_STUDENT; |
||
234 | $user_selected_language = api_get_interface_language(); |
||
235 | $db_table = Database :: get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS); |
||
236 | $sql = 'SELECT id FROM '.$db_table.' |
||
237 | WHERE (lang="'.$user_selected_language.'" OR lang IS NULL) '; |
||
238 | if (isset($user_id)) { |
||
239 | switch ($visibility) { |
||
240 | case self::VISIBLE_GUEST: |
||
241 | $sql .= " AND visible_guest = 1 "; |
||
242 | break; |
||
243 | case self::VISIBLE_STUDENT: |
||
244 | $sql .= " AND visible_student = 1 "; |
||
245 | break; |
||
246 | case self::VISIBLE_TEACHER: |
||
247 | $sql .= " AND visible_teacher = 1 "; |
||
248 | break; |
||
249 | } |
||
250 | } |
||
251 | |||
252 | $current_access_url_id = 1; |
||
253 | if (api_is_multiple_url_enabled()) { |
||
254 | $current_access_url_id = api_get_current_access_url_id(); |
||
255 | } |
||
256 | $sql .= " AND access_url_id = '$current_access_url_id' "; |
||
257 | |||
258 | |||
259 | $sql .= 'LIMIT '.$start.', 21'; |
||
260 | $announcements = Database::query($sql); |
||
261 | $i = 0; |
||
262 | while ($rows = Database::fetch_array($announcements)) { |
||
263 | $i++; |
||
264 | } |
||
265 | |||
266 | return $i; |
||
267 | } |
||
268 | |||
269 | /** |
||
270 | * Get all announcements |
||
271 | * @return array An array with all available system announcements (as php |
||
272 | * objects) |
||
273 | */ |
||
274 | View Code Duplication | public static function get_all_announcements() |
|
295 | |||
296 | /** |
||
297 | * Adds an announcement to the database |
||
298 | * @param string Title of the announcement |
||
299 | * @param string Content of the announcement |
||
300 | * @param string Start date (YYYY-MM-DD HH:II: SS) |
||
301 | * @param string End date (YYYY-MM-DD HH:II: SS) |
||
302 | * @param int Whether the announcement should be visible to teachers (1) or not (0) |
||
303 | * @param int Whether the announcement should be visible to students (1) or not (0) |
||
304 | * @param int Whether the announcement should be visible to anonymous users (1) or not (0) |
||
305 | * @param string The language for which the announvement should be shown. Leave null for all langages |
||
306 | * @param int Whether to send an e-mail to all users (1) or not (0) |
||
307 | * @return mixed insert_id on success, false on failure |
||
308 | */ |
||
309 | public static function add_announcement( |
||
424 | |||
425 | /** |
||
426 | * Makes the announcement id visible only for groups in groups_array |
||
427 | * @param int $announcement_id |
||
428 | * @param array $group_array array of group id |
||
429 | **/ |
||
430 | public static function announcement_for_groups($announcement_id, $group_array) |
||
460 | |||
461 | /** |
||
462 | * Gets the groups of this announce |
||
463 | * @param int announcement id |
||
464 | * @return array array of group id |
||
465 | **/ |
||
466 | View Code Duplication | public static function get_announcement_groups($announcement_id) |
|
484 | |||
485 | /** |
||
486 | * Updates an announcement to the database |
||
487 | * @param integer $id : id of the announcement |
||
488 | * @param string $title : title of the announcement |
||
489 | * @param string $content : content of the announcement |
||
490 | * @param array $date_start: start date of announcement (0 => day ; 1 => month ; 2 => year ; 3 => hour ; 4 => minute) |
||
491 | * @param array $date_end : end date of announcement (0 => day ; 1 => month ; 2 => year ; 3 => hour ; 4 => minute) |
||
492 | * @return bool True on success, false on failure |
||
493 | */ |
||
494 | public static function update_announcement( |
||
495 | $id, |
||
496 | $title, |
||
497 | $content, |
||
498 | $date_start, |
||
499 | $date_end, |
||
500 | $visible_teacher = 0, |
||
501 | $visible_student = 0, |
||
502 | $visible_guest = 0, |
||
503 | $lang = null, |
||
504 | $send_mail = 0, |
||
505 | $sendEmailTest = false |
||
506 | ) { |
||
507 | $em = Database::getManager(); |
||
508 | $announcement = $em->find('ChamiloCoreBundle:SysAnnouncement', $id); |
||
509 | |||
510 | if (!$announcement) { |
||
511 | return false; |
||
512 | } |
||
513 | |||
514 | $a_dateS = explode(' ', $date_start); |
||
515 | $a_arraySD = explode('-', $a_dateS[0]); |
||
516 | $a_arraySH = explode(':', $a_dateS[1]); |
||
517 | $date_start_to_compare = array_merge($a_arraySD, $a_arraySH); |
||
518 | |||
519 | $a_dateE = explode(' ', $date_end); |
||
520 | $a_arrayED = explode('-', $a_dateE[0]); |
||
521 | $a_arrayEH = explode(':', $a_dateE[1]); |
||
522 | $date_end_to_compare = array_merge($a_arrayED, $a_arrayEH); |
||
523 | |||
524 | $lang = is_null($lang) ? '' : $lang; |
||
525 | |||
526 | View Code Duplication | if (!checkdate($date_start_to_compare[1], $date_start_to_compare[2], $date_start_to_compare[0])) { |
|
527 | Display:: display_normal_message(get_lang('InvalidStartDate')); |
||
528 | |||
529 | return false; |
||
530 | } |
||
531 | |||
532 | View Code Duplication | if (($date_end_to_compare[1] || |
|
533 | $date_end_to_compare[2] || |
||
534 | $date_end_to_compare[0]) && |
||
535 | !checkdate($date_end_to_compare[1], $date_end_to_compare[2], $date_end_to_compare[0]) |
||
536 | ) { |
||
537 | Display :: display_normal_message(get_lang('InvalidEndDate')); |
||
538 | |||
539 | return false; |
||
540 | } |
||
541 | |||
542 | View Code Duplication | if (strlen(trim($title)) == 0) { |
|
543 | Display::display_normal_message(get_lang('InvalidTitle')); |
||
544 | |||
545 | return false; |
||
546 | } |
||
547 | |||
548 | $start = api_get_utc_datetime($date_start); |
||
549 | $end = api_get_utc_datetime($date_end); |
||
550 | |||
551 | //Fixing urls that are sent by email |
||
552 | //$content = str_replace('src=\"/home/', 'src=\"'.api_get_path(WEB_PATH).'home/', $content); |
||
553 | //$content = str_replace('file=/home/', 'file='.api_get_path(WEB_PATH).'home/', $content); |
||
554 | $content = str_replace('src=\"'.api_get_path(REL_HOME_PATH), 'src=\"'.api_get_path(WEB_PATH).api_get_path(REL_HOME_PATH), $content); |
||
555 | $content = str_replace('file='.api_get_path(REL_HOME_PATH), 'file='.api_get_path(WEB_PATH).api_get_path(REL_HOME_PATH), $content); |
||
556 | |||
557 | View Code Duplication | if ($sendEmailTest) { |
|
558 | SystemAnnouncementManager::send_system_announcement_by_email( |
||
559 | $title, |
||
560 | $content, |
||
561 | null, |
||
562 | null, |
||
563 | $lang, |
||
564 | $sendEmailTest |
||
565 | ); |
||
566 | } else { |
||
567 | if ($send_mail==1) { |
||
568 | SystemAnnouncementManager::send_system_announcement_by_email( |
||
569 | $title, |
||
570 | $content, |
||
571 | $visible_teacher, |
||
572 | $visible_student, |
||
573 | $lang |
||
574 | ); |
||
575 | } |
||
576 | } |
||
577 | |||
578 | $dateStart = new DateTime($start, new DateTimeZone('UTC')); |
||
579 | $dateEnd = new DateTime($end, new DateTimeZone('UTC')); |
||
580 | |||
581 | $announcement |
||
582 | ->setLang($lang) |
||
583 | ->setTitle($title) |
||
584 | ->setContent($content) |
||
585 | ->setDateStart($dateStart) |
||
586 | ->setDateEnd($dateEnd) |
||
587 | ->setVisibleTeacher($visible_teacher) |
||
588 | ->setVisibleStudent($visible_student) |
||
589 | ->setVisibleGuest($visible_guest) |
||
590 | ->setAccessUrlId(api_get_current_access_url_id()); |
||
591 | |||
592 | $em->merge($announcement); |
||
593 | $em->flush(); |
||
594 | |||
595 | return true; |
||
596 | } |
||
597 | |||
598 | /** |
||
599 | * Deletes an announcement |
||
600 | * @param int $id The identifier of the announcement that should be |
||
601 | * @return bool True on success, false on failure |
||
602 | */ |
||
603 | public static function delete_announcement($id) |
||
604 | { |
||
605 | $db_table = Database :: get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS); |
||
606 | $id = intval($id); |
||
607 | $sql = "DELETE FROM ".$db_table." WHERE id =".$id; |
||
608 | $res = Database::query($sql); |
||
609 | if ($res === false) { |
||
610 | return false; |
||
611 | } |
||
612 | return true; |
||
613 | } |
||
614 | |||
615 | /** |
||
616 | * Gets an announcement |
||
617 | * @param int $id The identifier of the announcement that should be |
||
618 | * @return object Object of class StdClass or the required class, containing the query result row |
||
619 | */ |
||
620 | public static function get_announcement($id) |
||
629 | |||
630 | /** |
||
631 | * Change the visibility of an announcement |
||
632 | * @param int $announcement_id |
||
633 | * @param int $user For who should the visibility be changed |
||
634 | * (possible values are VISIBLE_TEACHER, VISIBLE_STUDENT, VISIBLE_GUEST) |
||
635 | * @return bool True on success, false on failure |
||
636 | */ |
||
637 | public static function set_visibility($announcement_id, $user, $visible) |
||
659 | |||
660 | /** |
||
661 | * Send a system announcement by e-mail to all teachers/students depending on parameters |
||
662 | * @param string $title |
||
663 | * @param string $content |
||
664 | * @param int $teacher Whether to send to all teachers (1) or not (0) |
||
665 | * @param int $student Whether to send to all students (1) or not (0) |
||
666 | * @param string $language Language (optional, considered for all languages if left empty) |
||
667 | * @param bool $sendEmailTest |
||
668 | * @return bool True if the message was sent or there was no destination matching. False on database or e-mail sending error. |
||
669 | */ |
||
670 | public static function send_system_announcement_by_email( |
||
752 | |||
753 | /** |
||
754 | * Displays announcements as an slideshow |
||
755 | * @param int $visible VISIBLE_GUEST, VISIBLE_STUDENT or VISIBLE_TEACHER |
||
756 | * @param int $id The identifier of the announcement to display |
||
757 | */ |
||
758 | public static function display_announcements_slider($visible, $id = null) |
||
827 | |||
828 | /** |
||
829 | * Get the HTML code for an announcement |
||
830 | * @param int $announcementId The announcement ID |
||
831 | * @param int $visibility The announcement visibility |
||
832 | * @return string The HTML code |
||
833 | */ |
||
834 | public static function displayAnnouncement($announcementId, $visibility) |
||
878 | } |
||
879 |
This method has been deprecated. The supplier of the class has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.