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 Shim 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 Shim, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
26 | class Shim |
||
|
|||
27 | { |
||
28 | /** @var FrenchCalendar */ |
||
29 | private static $french_calendar; |
||
30 | |||
31 | /** @var GregorianCalendar */ |
||
32 | private static $gregorian_calendar; |
||
33 | |||
34 | /** @var JewishCalendar */ |
||
35 | private static $jewish_calendar; |
||
36 | |||
37 | /** @var JulianCalendar */ |
||
38 | private static $julian_calendar; |
||
39 | |||
40 | /** |
||
41 | * English names for the days of the week. |
||
42 | * |
||
43 | * @var string[] |
||
44 | */ |
||
45 | private static $DAY_NAMES = array( |
||
46 | 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', |
||
47 | ); |
||
48 | |||
49 | /** |
||
50 | * Abbreviated English names for the days of the week. |
||
51 | * |
||
52 | * @var string[] |
||
53 | */ |
||
54 | private static $DAY_NAMES_SHORT = array( |
||
55 | 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', |
||
56 | ); |
||
57 | |||
58 | /** @var string[] Names of the months of the Gregorian/Julian calendars */ |
||
59 | private static $MONTH_NAMES = array( |
||
60 | '', 'January', 'February', 'March', 'April', 'May', 'June', |
||
61 | 'July', 'August', 'September', 'October', 'November', 'December', |
||
62 | ); |
||
63 | |||
64 | /** @var string[] Abbreviated names of the months of the Gregorian/Julian calendars */ |
||
65 | private static $MONTH_NAMES_SHORT = array( |
||
66 | '', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec', |
||
67 | ); |
||
68 | |||
69 | /** @var string[] Name of the months of the French calendar */ |
||
70 | private static $MONTH_NAMES_FRENCH = array( |
||
71 | '', 'Vendemiaire', 'Brumaire', 'Frimaire', 'Nivose', 'Pluviose', 'Ventose', |
||
72 | 'Germinal', 'Floreal', 'Prairial', 'Messidor', 'Thermidor', 'Fructidor', 'Extra' |
||
73 | ); |
||
74 | |||
75 | /** @var string[] Names of the months of the Jewish calendar in a non-leap year */ |
||
76 | private static $MONTH_NAMES_JEWISH = array( |
||
77 | '', 'Tishri', 'Heshvan', 'Kislev', 'Tevet', 'Shevat', 'Adar', |
||
78 | 'Adar', 'Nisan', 'Iyyar', 'Sivan', 'Tammuz', 'Av', 'Elul', |
||
79 | ); |
||
80 | |||
81 | /** @var string[] Names of the months of the Jewish calendar in a leap year */ |
||
82 | private static $MONTH_NAMES_JEWISH_LEAP_YEAR = array( |
||
83 | '', 'Tishri', 'Heshvan', 'Kislev', 'Tevet', 'Shevat', 'Adar I', |
||
84 | 'Adar II', 'Nisan', 'Iyyar', 'Sivan', 'Tammuz', 'Av', 'Elul', |
||
85 | ); |
||
86 | |||
87 | /** @var string[] Names of the months of the Jewish calendar (before PHP bug 54254 was fixed) */ |
||
88 | private static $MONTH_NAMES_JEWISH_54254 = array( |
||
89 | '', 'Tishri', 'Heshvan', 'Kislev', 'Tevet', 'Shevat', 'AdarI', |
||
90 | 'AdarII', 'Nisan', 'Iyyar', 'Sivan', 'Tammuz', 'Av', 'Elul', |
||
91 | ); |
||
92 | |||
93 | /** |
||
94 | * Create the necessary shims to emulate the ext/calendar package. |
||
95 | * |
||
96 | * @return void |
||
97 | */ |
||
98 | public static function create() |
||
107 | |||
108 | /** |
||
109 | * Do we need to emulate PHP bug #54254? |
||
110 | * |
||
111 | * This bug relates to the names used for months 6 and 7 in the Jewish calendar. |
||
112 | * |
||
113 | * It was fixed in PHP 5.5.0 |
||
114 | * |
||
115 | * @link https://bugs.php.net/bug.php?id=54254 |
||
116 | * |
||
117 | * @return bool |
||
118 | */ |
||
119 | public static function shouldEmulateBug54254() |
||
123 | |||
124 | /** |
||
125 | * Do we need to emulate PHP bug #67960? |
||
126 | * |
||
127 | * This bug relates to the constants CAL_DOW_SHORT and CAL_DOW_LONG. |
||
128 | * |
||
129 | * It was fixed in PHP 5.6.5 and 5.5.21 |
||
130 | * |
||
131 | * @link https://bugs.php.net/bug.php?id=67960 |
||
132 | * @link https://github.com/php/php-src/pull/806 |
||
133 | * |
||
134 | * @return bool |
||
135 | */ |
||
136 | public static function shouldEmulateBug67960() |
||
140 | |||
141 | /** |
||
142 | * Do we need to emulate PHP bug #67976? |
||
143 | * |
||
144 | * This bug relates to the number of days in the month 13 of year 14 in |
||
145 | * the French calendar. |
||
146 | * |
||
147 | * It was fixed in PHP 5.6.25 and 7.0.10 |
||
148 | * |
||
149 | * @link https://bugs.php.net/bug.php?id=67976 |
||
150 | * |
||
151 | * @return bool |
||
152 | */ |
||
153 | public static function shouldEmulateBug67976() |
||
157 | |||
158 | /** |
||
159 | * Return the number of days in a month for a given year and calendar. |
||
160 | * |
||
161 | * Shim implementation of cal_days_in_month() |
||
162 | * |
||
163 | * @link https://php.net/cal_days_in_month |
||
164 | * @link https://bugs.php.net/bug.php?id=67976 |
||
165 | * |
||
166 | * @param int $calendar_id |
||
167 | * @param int $month |
||
168 | * @param int $year |
||
169 | * |
||
170 | * @return int|bool The number of days in the specified month, or false on error |
||
171 | */ |
||
172 | public static function calDaysInMonth($calendar_id, $month, $year) |
||
191 | |||
192 | /** |
||
193 | * Calculate the number of days in a month in a specified (Gregorian or Julian) calendar. |
||
194 | * |
||
195 | * @param CalendarInterface $calendar |
||
196 | * @param int $year |
||
197 | * @param int $month |
||
198 | * |
||
199 | * @return int|bool |
||
200 | */ |
||
201 | private static function calDaysInMonthCalendar(CalendarInterface $calendar, $year, $month) |
||
211 | |||
212 | /** |
||
213 | * Calculate the number of days in a month in the French calendar. |
||
214 | * |
||
215 | * Mimic PHP’s validation of the parameters |
||
216 | * |
||
217 | * @param int $year |
||
218 | * @param int $month |
||
219 | * |
||
220 | * @return int|bool |
||
221 | */ |
||
222 | private static function calDaysInMonthFrench($year, $month) |
||
234 | |||
235 | /** |
||
236 | * Converts from Julian Day Count to a supported calendar. |
||
237 | * |
||
238 | * Shim implementation of cal_from_jd() |
||
239 | * |
||
240 | * @link https://php.net/cal_from_jd |
||
241 | * |
||
242 | * @param int $julian_day Julian Day number |
||
243 | * @param int $calendar_id Calendar constant |
||
244 | * |
||
245 | * @return array|bool |
||
246 | */ |
||
247 | public static function calFromJd($julian_day, $calendar_id) |
||
276 | |||
277 | /** |
||
278 | * Convert a Julian day number to a calendar and provide details. |
||
279 | * |
||
280 | * @param int $julian_day |
||
281 | * @param string $mdy |
||
282 | * @param string[] $months |
||
283 | * @param string[] $months_short |
||
284 | * |
||
285 | * @return array |
||
286 | */ |
||
287 | private static function calFromJdCalendar($julian_day, $mdy, $months, $months_short) |
||
303 | |||
304 | /** |
||
305 | * Returns information about a particular calendar. |
||
306 | * |
||
307 | * Shim implementation of cal_info() |
||
308 | * |
||
309 | * @link https://php.net/cal_info |
||
310 | * |
||
311 | * @param int $calendar_id |
||
312 | * |
||
313 | * @return array|bool |
||
314 | */ |
||
315 | public static function calInfo($calendar_id) |
||
344 | |||
345 | /** |
||
346 | * Returns information about the French calendar. |
||
347 | * |
||
348 | * @param string[] $month_names |
||
349 | * @param string[] $month_names_short |
||
350 | * @param int $max_days_in_month |
||
351 | * @param string $calendar_name |
||
352 | * @param string $calendar_symbol |
||
353 | * |
||
354 | * @return array |
||
355 | */ |
||
356 | private static function calInfoCalendar($month_names, $month_names_short, $max_days_in_month, $calendar_name, $calendar_symbol) |
||
366 | |||
367 | /** |
||
368 | * Converts from a supported calendar to Julian Day Count |
||
369 | * |
||
370 | * Shim implementation of cal_to_jd() |
||
371 | * |
||
372 | * @link https://php.net/cal_to_jd |
||
373 | * |
||
374 | * @param int $calendar_id |
||
375 | * @param int $month |
||
376 | * @param int $day |
||
377 | * @param int $year |
||
378 | * |
||
379 | * @return int|bool |
||
380 | */ |
||
381 | public static function calToJd($calendar_id, $month, $day, $year) |
||
400 | |||
401 | /** |
||
402 | * Get Unix timestamp for midnight on Easter of a given year. |
||
403 | * |
||
404 | * Shim implementation of easter_date() |
||
405 | * |
||
406 | * @link https://php.net/easter_date |
||
407 | * |
||
408 | * @param int $year |
||
409 | * |
||
410 | * @return int|bool |
||
411 | */ |
||
412 | public static function easterDate($year) |
||
430 | |||
431 | /** |
||
432 | * Get number of days after March 21 on which Easter falls for a given year. |
||
433 | * |
||
434 | * Shim implementation of easter_days() |
||
435 | * |
||
436 | * @link https://php.net/easter_days |
||
437 | * |
||
438 | * @param int $year |
||
439 | * @param int $method Use the Julian or Gregorian calendar |
||
440 | * |
||
441 | * @return int |
||
442 | */ |
||
443 | public static function easterDays($year, $method) |
||
454 | |||
455 | /** |
||
456 | * Converts a date from the French Republican Calendar to a Julian Day Count. |
||
457 | * |
||
458 | * Shim implementation of FrenchToJD() |
||
459 | * |
||
460 | * @link https://php.net/FrenchToJD |
||
461 | * |
||
462 | * @param int $month |
||
463 | * @param int $day |
||
464 | * @param int $year |
||
465 | * |
||
466 | * @return int |
||
467 | */ |
||
468 | public static function frenchToJd($month, $day, $year) |
||
476 | |||
477 | /** |
||
478 | * Converts a Gregorian date to Julian Day Count. |
||
479 | * |
||
480 | * Shim implementation of GregorianToJD() |
||
481 | * |
||
482 | * @link https://php.net/GregorianToJD |
||
483 | * |
||
484 | * @param int $month |
||
485 | * @param int $day |
||
486 | * @param int $year |
||
487 | * |
||
488 | * @return int |
||
489 | */ |
||
490 | public static function gregorianToJd($month, $day, $year) |
||
498 | |||
499 | /** |
||
500 | * Returns the day of the week. |
||
501 | * |
||
502 | * Shim implementation of JDDayOfWeek() |
||
503 | * |
||
504 | * @link https://php.net/JDDayOfWeek |
||
505 | * @link https://bugs.php.net/bug.php?id=67960 |
||
506 | * |
||
507 | * @param int $julian_day |
||
508 | * @param int $mode |
||
509 | * |
||
510 | * @return int|string |
||
511 | */ |
||
512 | public static function jdDayOfWeek($julian_day, $mode) |
||
530 | |||
531 | /** |
||
532 | * Returns a month name. |
||
533 | * |
||
534 | * Shim implementation of JDMonthName() |
||
535 | * |
||
536 | * @link https://php.net/JDMonthName |
||
537 | * |
||
538 | * @param int $julian_day |
||
539 | * @param int $mode |
||
540 | * |
||
541 | * @return string |
||
542 | */ |
||
543 | public static function jdMonthName($julian_day, $mode) |
||
566 | |||
567 | /** |
||
568 | * Calculate the month-name for a given julian day, in a given calendar, |
||
569 | * with given set of month names. |
||
570 | * |
||
571 | * @param CalendarInterface $calendar |
||
572 | * @param int $julian_day |
||
573 | * @param string[] $months |
||
574 | * |
||
575 | * @return string |
||
576 | */ |
||
577 | private static function jdMonthNameCalendar(CalendarInterface $calendar, $julian_day, $months) |
||
583 | |||
584 | /** |
||
585 | * Determine which month names to use for the Jewish calendar. |
||
586 | * |
||
587 | * @param int $julian_day |
||
588 | * |
||
589 | * @return string[] |
||
590 | */ |
||
591 | private static function jdMonthNameJewishMonths($julian_day) |
||
601 | |||
602 | /** |
||
603 | * Convert a Julian day in a specific calendar to a day/month/year. |
||
604 | * |
||
605 | * Julian days outside the specified range are returned as “0/0/0”. |
||
606 | * |
||
607 | * @param CalendarInterface $calendar |
||
608 | * @param int $julian_day |
||
609 | * @param int $min_jd |
||
610 | * @param int $max_jd |
||
611 | * |
||
612 | * @return string |
||
613 | */ |
||
614 | private static function jdToCalendar(CalendarInterface $calendar, $julian_day, $min_jd, $max_jd) |
||
624 | |||
625 | /** |
||
626 | * Converts a Julian Day Count to the French Republican Calendar. |
||
627 | * |
||
628 | * Shim implementation of JDToFrench() |
||
629 | * |
||
630 | * @link https://php.net/JDToFrench |
||
631 | * |
||
632 | * @param int $julian_day A Julian Day number |
||
633 | * |
||
634 | * @return string A string of the form "month/day/year" |
||
635 | */ |
||
636 | public static function jdToFrench($julian_day) |
||
642 | |||
643 | /** |
||
644 | * Converts Julian Day Count to Gregorian date. |
||
645 | * |
||
646 | * Shim implementation of JDToGregorian() |
||
647 | * |
||
648 | * @link https://php.net/JDToGregorian |
||
649 | * |
||
650 | * @param int $julian_day A Julian Day number |
||
651 | * |
||
652 | * @return string A string of the form "month/day/year" |
||
653 | */ |
||
654 | View Code Duplication | public static function jdToGregorian($julian_day) |
|
661 | |||
662 | /** |
||
663 | * Converts a Julian day count to a Jewish calendar date. |
||
664 | * |
||
665 | * Shim implementation of JdtoJjewish() |
||
666 | * |
||
667 | * @link https://php.net/JdtoJewish |
||
668 | * |
||
669 | * @param int $julian_day A Julian Day number |
||
670 | * @param bool $hebrew If true, the date is returned in Hebrew text |
||
671 | * @param int $fl If $hebrew is true, then add alafim and gereshayim to the text |
||
672 | * |
||
673 | * @return string|bool A string of the form "month/day/year", or false on error |
||
674 | */ |
||
675 | public static function jdToJewish($julian_day, $hebrew, $fl) |
||
695 | |||
696 | /** |
||
697 | * Converts a Julian Day Count to a Julian Calendar Date. |
||
698 | * |
||
699 | * Shim implementation of JDToJulian() |
||
700 | * |
||
701 | * @link https://php.net/JDToJulian |
||
702 | * |
||
703 | * @param int $julian_day A Julian Day number |
||
704 | * |
||
705 | * @return string A string of the form "month/day/year" |
||
706 | */ |
||
707 | View Code Duplication | public static function jdToJulian($julian_day) |
|
714 | |||
715 | /** |
||
716 | * Convert Julian Day to Unix timestamp. |
||
717 | * |
||
718 | * Shim implementation of jdtounix() |
||
719 | * |
||
720 | * @link https://php.net/jdtounix |
||
721 | * |
||
722 | * @param int $julian_day |
||
723 | * |
||
724 | * @return int|false |
||
725 | */ |
||
726 | public static function jdToUnix($julian_day) |
||
734 | |||
735 | /** |
||
736 | * Converts a date in the Jewish Calendar to Julian Day Count. |
||
737 | * |
||
738 | * Shim implementation of JewishToJD() |
||
739 | * |
||
740 | * @link https://php.net/JewishToJD |
||
741 | * |
||
742 | * @param int $month |
||
743 | * @param int $day |
||
744 | * @param int $year |
||
745 | * |
||
746 | * @return int |
||
747 | */ |
||
748 | public static function jewishToJd($month, $day, $year) |
||
756 | |||
757 | /** |
||
758 | * Converts a Julian Calendar date to Julian Day Count. |
||
759 | * |
||
760 | * Shim implementation of JdToJulian() |
||
761 | * |
||
762 | * @link https://php.net/JdToJulian |
||
763 | * |
||
764 | * @param int $month |
||
765 | * @param int $day |
||
766 | * @param int $year |
||
767 | * |
||
768 | * @return int |
||
769 | */ |
||
770 | public static function julianToJd($month, $day, $year) |
||
778 | |||
779 | /** |
||
780 | * Convert Unix timestamp to Julian Day. |
||
781 | * |
||
782 | * Shim implementation of unixtojd() |
||
783 | * |
||
784 | * @link https://php.net/unixtojd |
||
785 | * |
||
786 | * @param int $timestamp |
||
787 | * |
||
788 | * @return false|int |
||
789 | */ |
||
790 | public static function unixToJd($timestamp) |
||
799 | } |
||
800 |
This check examines a number of code elements and verifies that they conform to the given naming conventions.
You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.