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:
1 | <?php |
||
24 | class FrenchDate extends CalendarDate { |
||
25 | /** @var int[] Convert GEDCOM month names to month numbers */ |
||
26 | public static $MONTH_ABBREV = ['' => 0, 'VEND' => 1, 'BRUM' => 2, 'FRIM' => 3, 'NIVO' => 4, 'PLUV' => 5, 'VENT' => 6, 'GERM' => 7, 'FLOR' => 8, 'PRAI' => 9, 'MESS' => 10, 'THER' => 11, 'FRUC' => 12, 'COMP' => 13]; |
||
27 | |||
28 | /** |
||
29 | * Create a date from either: |
||
30 | * a Julian day number |
||
31 | * day/month/year strings from a GEDCOM date |
||
32 | * another CalendarDate object |
||
33 | * |
||
34 | * @param array|int|CalendarDate $date |
||
35 | */ |
||
36 | public function __construct($date) { |
||
40 | |||
41 | /** |
||
42 | * Full month name in nominative case. |
||
43 | * |
||
44 | * @param int $month_number |
||
45 | * @param bool $leap_year Some calendars use leap months |
||
46 | * |
||
47 | * @return string |
||
48 | */ |
||
49 | View Code Duplication | public static function monthNameNominativeCase($month_number, $leap_year) { |
|
|
|||
50 | static $translated_month_names; |
||
51 | |||
52 | if ($translated_month_names === null) { |
||
53 | $translated_month_names = [ |
||
54 | 0 => '', |
||
55 | 1 => /* I18N: a month in the French republican calendar */ I18N::translateContext('NOMINATIVE', 'Vendemiaire'), |
||
56 | 2 => /* I18N: a month in the French republican calendar */ I18N::translateContext('NOMINATIVE', 'Brumaire'), |
||
57 | 3 => /* I18N: a month in the French republican calendar */ I18N::translateContext('NOMINATIVE', 'Frimaire'), |
||
58 | 4 => /* I18N: a month in the French republican calendar */ I18N::translateContext('NOMINATIVE', 'Nivose'), |
||
59 | 5 => /* I18N: a month in the French republican calendar */ I18N::translateContext('NOMINATIVE', 'Pluviose'), |
||
60 | 6 => /* I18N: a month in the French republican calendar */ I18N::translateContext('NOMINATIVE', 'Ventose'), |
||
61 | 7 => /* I18N: a month in the French republican calendar */ I18N::translateContext('NOMINATIVE', 'Germinal'), |
||
62 | 8 => /* I18N: a month in the French republican calendar */ I18N::translateContext('NOMINATIVE', 'Floreal'), |
||
63 | 9 => /* I18N: a month in the French republican calendar */ I18N::translateContext('NOMINATIVE', 'Prairial'), |
||
64 | 10 => /* I18N: a month in the French republican calendar */ I18N::translateContext('NOMINATIVE', 'Messidor'), |
||
65 | 11 => /* I18N: a month in the French republican calendar */ I18N::translateContext('NOMINATIVE', 'Thermidor'), |
||
66 | 12 => /* I18N: a month in the French republican calendar */ I18N::translateContext('NOMINATIVE', 'Fructidor'), |
||
67 | 13 => /* I18N: a month in the French republican calendar */ I18N::translateContext('NOMINATIVE', 'jours complementaires'), |
||
68 | ]; |
||
69 | } |
||
70 | |||
71 | return $translated_month_names[$month_number]; |
||
72 | } |
||
73 | |||
74 | /** |
||
75 | * Full month name in genitive case. |
||
76 | * |
||
77 | * @param int $month_number |
||
78 | * @param bool $leap_year Some calendars use leap months |
||
79 | * |
||
80 | * @return string |
||
81 | */ |
||
82 | View Code Duplication | protected function monthNameGenitiveCase($month_number, $leap_year) { |
|
83 | static $translated_month_names; |
||
84 | |||
85 | if ($translated_month_names === null) { |
||
86 | $translated_month_names = [ |
||
87 | 0 => '', |
||
88 | 1 => /* I18N: a month in the French republican calendar */ I18N::translateContext('GENITIVE', 'Vendemiaire'), |
||
89 | 2 => /* I18N: a month in the French republican calendar */ I18N::translateContext('GENITIVE', 'Brumaire'), |
||
90 | 3 => /* I18N: a month in the French republican calendar */ I18N::translateContext('GENITIVE', 'Frimaire'), |
||
91 | 4 => /* I18N: a month in the French republican calendar */ I18N::translateContext('GENITIVE', 'Nivose'), |
||
92 | 5 => /* I18N: a month in the French republican calendar */ I18N::translateContext('GENITIVE', 'Pluviose'), |
||
93 | 6 => /* I18N: a month in the French republican calendar */ I18N::translateContext('GENITIVE', 'Ventose'), |
||
94 | 7 => /* I18N: a month in the French republican calendar */ I18N::translateContext('GENITIVE', 'Germinal'), |
||
95 | 8 => /* I18N: a month in the French republican calendar */ I18N::translateContext('GENITIVE', 'Floreal'), |
||
96 | 9 => /* I18N: a month in the French republican calendar */ I18N::translateContext('GENITIVE', 'Prairial'), |
||
97 | 10 => /* I18N: a month in the French republican calendar */ I18N::translateContext('GENITIVE', 'Messidor'), |
||
98 | 11 => /* I18N: a month in the French republican calendar */ I18N::translateContext('GENITIVE', 'Thermidor'), |
||
99 | 12 => /* I18N: a month in the French republican calendar */ I18N::translateContext('GENITIVE', 'Fructidor'), |
||
100 | 13 => /* I18N: a month in the French republican calendar */ I18N::translateContext('GENITIVE', 'jours complementaires'), |
||
101 | ]; |
||
102 | } |
||
103 | |||
104 | return $translated_month_names[$month_number]; |
||
105 | } |
||
106 | |||
107 | /** |
||
108 | * Full month name in locative case. |
||
109 | * |
||
110 | * @param int $month_number |
||
111 | * @param bool $leap_year Some calendars use leap months |
||
112 | * |
||
113 | * @return string |
||
114 | */ |
||
115 | View Code Duplication | protected function monthNameLocativeCase($month_number, $leap_year) { |
|
116 | static $translated_month_names; |
||
117 | |||
118 | if ($translated_month_names === null) { |
||
119 | $translated_month_names = [ |
||
120 | 0 => '', |
||
121 | 1 => /* I18N: a month in the French republican calendar */ I18N::translateContext('LOCATIVE', 'Vendemiaire'), |
||
122 | 2 => /* I18N: a month in the French republican calendar */ I18N::translateContext('LOCATIVE', 'Brumaire'), |
||
123 | 3 => /* I18N: a month in the French republican calendar */ I18N::translateContext('LOCATIVE', 'Frimaire'), |
||
124 | 4 => /* I18N: a month in the French republican calendar */ I18N::translateContext('LOCATIVE', 'Nivose'), |
||
125 | 5 => /* I18N: a month in the French republican calendar */ I18N::translateContext('LOCATIVE', 'Pluviose'), |
||
126 | 6 => /* I18N: a month in the French republican calendar */ I18N::translateContext('LOCATIVE', 'Ventose'), |
||
127 | 7 => /* I18N: a month in the French republican calendar */ I18N::translateContext('LOCATIVE', 'Germinal'), |
||
128 | 8 => /* I18N: a month in the French republican calendar */ I18N::translateContext('LOCATIVE', 'Floreal'), |
||
129 | 9 => /* I18N: a month in the French republican calendar */ I18N::translateContext('LOCATIVE', 'Prairial'), |
||
130 | 10 => /* I18N: a month in the French republican calendar */ I18N::translateContext('LOCATIVE', 'Messidor'), |
||
131 | 11 => /* I18N: a month in the French republican calendar */ I18N::translateContext('LOCATIVE', 'Thermidor'), |
||
132 | 12 => /* I18N: a month in the French republican calendar */ I18N::translateContext('LOCATIVE', 'Fructidor'), |
||
133 | 13 => /* I18N: a month in the French republican calendar */ I18N::translateContext('LOCATIVE', 'jours complementaires'), |
||
134 | ]; |
||
135 | } |
||
136 | |||
137 | return $translated_month_names[$month_number]; |
||
138 | } |
||
139 | |||
140 | /** |
||
141 | * Full month name in instrumental case. |
||
142 | * |
||
143 | * @param int $month_number |
||
144 | * @param bool $leap_year Some calendars use leap months |
||
145 | * |
||
146 | * @return string |
||
147 | */ |
||
148 | View Code Duplication | protected function monthNameInstrumentalCase($month_number, $leap_year) { |
|
149 | static $translated_month_names; |
||
150 | |||
151 | if ($translated_month_names === null) { |
||
152 | $translated_month_names = [ |
||
153 | 0 => '', |
||
154 | 1 => /* I18N: a month in the French republican calendar */ I18N::translateContext('INSTRUMENTAL', 'Vendemiaire'), |
||
155 | 2 => /* I18N: a month in the French republican calendar */ I18N::translateContext('INSTRUMENTAL', 'Brumaire'), |
||
156 | 3 => /* I18N: a month in the French republican calendar */ I18N::translateContext('INSTRUMENTAL', 'Frimaire'), |
||
157 | 4 => /* I18N: a month in the French republican calendar */ I18N::translateContext('INSTRUMENTAL', 'Nivose'), |
||
158 | 5 => /* I18N: a month in the French republican calendar */ I18N::translateContext('INSTRUMENTAL', 'Pluviose'), |
||
159 | 6 => /* I18N: a month in the French republican calendar */ I18N::translateContext('INSTRUMENTAL', 'Ventose'), |
||
160 | 7 => /* I18N: a month in the French republican calendar */ I18N::translateContext('INSTRUMENTAL', 'Germinal'), |
||
161 | 8 => /* I18N: a month in the French republican calendar */ I18N::translateContext('INSTRUMENTAL', 'Floreal'), |
||
162 | 9 => /* I18N: a month in the French republican calendar */ I18N::translateContext('INSTRUMENTAL', 'Prairial'), |
||
163 | 10 => /* I18N: a month in the French republican calendar */ I18N::translateContext('INSTRUMENTAL', 'Messidor'), |
||
164 | 11 => /* I18N: a month in the French republican calendar */ I18N::translateContext('INSTRUMENTAL', 'Thermidor'), |
||
165 | 12 => /* I18N: a month in the French republican calendar */ I18N::translateContext('INSTRUMENTAL', 'Fructidor'), |
||
166 | 13 => /* I18N: a month in the French republican calendar */ I18N::translateContext('INSTRUMENTAL', 'jours complementaires'), |
||
167 | ]; |
||
168 | } |
||
169 | |||
170 | return $translated_month_names[$month_number]; |
||
171 | } |
||
172 | |||
173 | /** |
||
174 | * Abbreviated month name |
||
175 | * |
||
176 | * @param int $month_number |
||
177 | * @param bool $leap_year Some calendars use leap months |
||
178 | * |
||
179 | * @return string |
||
180 | */ |
||
181 | protected function monthNameAbbreviated($month_number, $leap_year) { |
||
184 | |||
185 | /** |
||
186 | * Full day of th eweek |
||
187 | * |
||
188 | * @param int $day_number |
||
189 | * |
||
190 | * @return string |
||
191 | */ |
||
192 | public function dayNames($day_number) { |
||
193 | static $translated_day_names; |
||
194 | |||
195 | if ($translated_day_names === null) { |
||
196 | $translated_day_names = [ |
||
197 | 0 => /* I18N: The first day in the French republican calendar */ I18N::translate('Primidi'), |
||
198 | 1 => /* I18N: The second day in the French republican calendar */ I18N::translate('Duodi'), |
||
199 | 2 => /* I18N: The third day in the French republican calendar */ I18N::translate('Tridi'), |
||
200 | 3 => /* I18N: The fourth day in the French republican calendar */ I18N::translate('Quartidi'), |
||
201 | 4 => /* I18N: The fifth day in the French republican calendar */ I18N::translate('Quintidi'), |
||
202 | 5 => /* I18N: The sixth day in the French republican calendar */ I18N::translate('Sextidi'), |
||
203 | 6 => /* I18N: The seventh day in the French republican calendar */ I18N::translate('Septidi'), |
||
204 | 7 => /* I18N: The eighth day in the French republican calendar */ I18N::translate('Octidi'), |
||
205 | 8 => /* I18N: The ninth day in the French republican calendar */ I18N::translate('Nonidi'), |
||
206 | 9 => /* I18N: The tenth day in the French republican calendar */ I18N::translate('Decidi'), |
||
207 | ]; |
||
208 | } |
||
209 | |||
210 | return $translated_day_names[$day_number]; |
||
211 | } |
||
212 | |||
213 | /** |
||
214 | * Abbreviated day of the week |
||
215 | * |
||
216 | * @param int $day_number |
||
217 | * |
||
218 | * @return string |
||
219 | */ |
||
220 | protected function dayNamesAbbreviated($day_number) { |
||
223 | |||
224 | /** |
||
225 | * Generate the %Y format for a date. |
||
226 | * |
||
227 | * @return string |
||
228 | */ |
||
229 | protected function formatLongYear() { |
||
232 | } |
||
233 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.