Total Complexity | 53 |
Total Lines | 500 |
Duplicated Lines | 10.2 % |
Changes | 0 |
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 WordPoints_Installable 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 WordPoints_Installable, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
18 | abstract class WordPoints_Installable implements WordPoints_InstallableI { |
||
19 | |||
20 | /** |
||
21 | * The type of entity. |
||
22 | * |
||
23 | * For example, 'module' or 'component'. |
||
24 | * |
||
25 | * Note that this is singular, even though in the 'wordpoints_data' option the |
||
26 | * plural forms are used for legacy reasons. |
||
27 | * |
||
28 | * @since 2.4.0 |
||
29 | * |
||
30 | * @var string |
||
31 | */ |
||
32 | protected $type; |
||
33 | |||
34 | /** |
||
35 | * The slug of this entity. |
||
36 | * |
||
37 | * @since 2.4.0 |
||
38 | * |
||
39 | * @var string |
||
40 | */ |
||
41 | protected $slug; |
||
42 | |||
43 | /** |
||
44 | * @since 2.4.0 |
||
45 | */ |
||
46 | public function get_slug() { |
||
48 | } |
||
49 | |||
50 | /** |
||
51 | * @since 2.4.0 |
||
52 | */ |
||
53 | public function get_db_version( $network = false ) { |
||
54 | |||
55 | $wordpoints_data = wordpoints_get_maybe_network_array_option( |
||
56 | 'wordpoints_data' |
||
57 | , $network |
||
58 | ); |
||
59 | |||
60 | if ( 'wordpoints' === $this->slug ) { |
||
61 | |||
62 | if ( isset( $wordpoints_data['version'] ) ) { |
||
63 | return $wordpoints_data['version']; |
||
64 | } |
||
65 | |||
66 | } elseif ( isset( $wordpoints_data[ "{$this->type}s" ][ $this->slug ]['version'] ) ) { |
||
67 | return $wordpoints_data[ "{$this->type}s" ][ $this->slug ]['version']; |
||
68 | } |
||
69 | |||
70 | return false; |
||
71 | } |
||
72 | |||
73 | /** |
||
74 | * @since 2.4.0 |
||
75 | */ |
||
76 | public function set_db_version( $version = null, $network = false ) { |
||
77 | |||
78 | if ( null === $version ) { |
||
79 | $version = $this->get_version(); |
||
80 | } |
||
81 | |||
82 | $wordpoints_data = wordpoints_get_maybe_network_array_option( |
||
83 | 'wordpoints_data' |
||
84 | , $network |
||
85 | ); |
||
86 | |||
87 | if ( 'wordpoints' === $this->slug ) { |
||
88 | $wordpoints_data['version'] = $version; |
||
89 | } else { |
||
90 | $wordpoints_data[ "{$this->type}s" ][ $this->slug ]['version'] = $version; |
||
91 | } |
||
92 | |||
93 | wordpoints_update_maybe_network_option( |
||
94 | 'wordpoints_data' |
||
95 | , $wordpoints_data |
||
96 | , $network |
||
97 | ); |
||
98 | } |
||
99 | |||
100 | /** |
||
101 | * @since 2.4.0 |
||
102 | */ |
||
103 | public function unset_db_version( $network = false ) { |
||
104 | |||
105 | $wordpoints_data = wordpoints_get_maybe_network_array_option( |
||
106 | 'wordpoints_data' |
||
107 | , $network |
||
108 | ); |
||
109 | |||
110 | if ( 'wordpoints' === $this->slug ) { |
||
111 | unset( $wordpoints_data['version'] ); |
||
112 | } else { |
||
113 | unset( $wordpoints_data[ "{$this->type}s" ][ $this->slug ]['version'] ); |
||
114 | } |
||
115 | |||
116 | wordpoints_update_maybe_network_option( |
||
117 | 'wordpoints_data' |
||
118 | , $wordpoints_data |
||
119 | , $network |
||
120 | ); |
||
121 | } |
||
122 | |||
123 | /** |
||
124 | * @since 2.4.0 |
||
125 | */ |
||
126 | public function is_network_installed() { |
||
127 | |||
128 | $network_installed = wordpoints_get_array_option( |
||
129 | 'wordpoints_network_installed' |
||
130 | , 'site' |
||
131 | ); |
||
132 | |||
133 | return isset( $network_installed[ $this->type ][ $this->slug ] ); |
||
134 | } |
||
135 | |||
136 | /** |
||
137 | * @since 2.4.0 |
||
138 | */ |
||
139 | public function set_network_installed() { |
||
140 | $this->set_option( 'network_installed' ); |
||
141 | } |
||
142 | |||
143 | /** |
||
144 | * @since 2.4.0 |
||
145 | */ |
||
146 | public function unset_network_installed() { |
||
147 | $this->unset_option( 'network_installed' ); |
||
148 | } |
||
149 | |||
150 | /** |
||
151 | * @since 2.4.0 |
||
152 | */ |
||
153 | public function set_network_install_skipped() { |
||
154 | $this->set_option( 'network_install_skipped' ); |
||
155 | } |
||
156 | |||
157 | /** |
||
158 | * @since 2.4.0 |
||
159 | */ |
||
160 | public function unset_network_install_skipped() { |
||
161 | $this->unset_option( 'network_install_skipped' ); |
||
162 | } |
||
163 | |||
164 | /** |
||
165 | * @since 2.4.0 |
||
166 | */ |
||
167 | public function set_network_update_skipped( $updating_from = null ) { |
||
168 | |||
169 | if ( ! isset( $updating_from ) ) { |
||
170 | $updating_from = $this->get_db_version( true ); |
||
171 | } |
||
172 | |||
173 | $this->set_option( 'network_update_skipped', $updating_from ); |
||
174 | } |
||
175 | |||
176 | /** |
||
177 | * @since 2.4.0 |
||
178 | */ |
||
179 | public function unset_network_update_skipped() { |
||
180 | $this->unset_option( 'network_update_skipped' ); |
||
181 | } |
||
182 | |||
183 | /** |
||
184 | * Sets an option in the database for this entity. |
||
185 | * |
||
186 | * @since 2.4.0 |
||
187 | * |
||
188 | * @param string $option The name of the option to set. |
||
189 | * @param mixed $value The value of the option. |
||
190 | */ |
||
191 | View Code Duplication | protected function set_option( $option, $value = true ) { |
|
|
|||
192 | |||
193 | $data = wordpoints_get_array_option( |
||
194 | "wordpoints_{$option}" |
||
195 | , 'site' |
||
196 | ); |
||
197 | |||
198 | $data[ $this->type ][ $this->slug ] = $value; |
||
199 | |||
200 | update_site_option( "wordpoints_{$option}", $data ); |
||
201 | } |
||
202 | |||
203 | /** |
||
204 | * Deletes an option in the database for this entity. |
||
205 | * |
||
206 | * @since 2.4.0 |
||
207 | * |
||
208 | * @param string $option The name of the option to delete. |
||
209 | */ |
||
210 | View Code Duplication | protected function unset_option( $option ) { |
|
211 | |||
212 | $data = wordpoints_get_array_option( |
||
213 | "wordpoints_{$option}" |
||
214 | , 'site' |
||
215 | ); |
||
216 | |||
217 | unset( $data[ $this->type ][ $this->slug ] ); |
||
218 | |||
219 | update_site_option( "wordpoints_{$option}", $data ); |
||
220 | } |
||
221 | |||
222 | /** |
||
223 | * @since 2.4.0 |
||
224 | */ |
||
225 | public function get_installed_site_ids() { |
||
226 | |||
227 | if ( $this->is_network_installed() ) { |
||
228 | |||
229 | $site_ids = $this->get_all_site_ids(); |
||
230 | |||
231 | } else { |
||
232 | |||
233 | $site_ids = wordpoints_get_array_option( |
||
234 | $this->get_installed_site_ids_option_name() |
||
235 | , 'site' |
||
236 | ); |
||
237 | |||
238 | $site_ids = $this->validate_site_ids( $site_ids ); |
||
239 | } |
||
240 | |||
241 | return $site_ids; |
||
242 | } |
||
243 | |||
244 | /** |
||
245 | * Gets the name of the option where the list of installed sites is stored. |
||
246 | * |
||
247 | * @since 2.4.0 |
||
248 | * |
||
249 | * @return string The option name. |
||
250 | */ |
||
251 | protected function get_installed_site_ids_option_name() { |
||
252 | |||
253 | if ( 'wordpoints' === $this->slug ) { |
||
254 | $option_prefix = 'wordpoints'; |
||
255 | } elseif ( 'component' === $this->type ) { |
||
256 | $option_prefix = "wordpoints_{$this->slug}"; |
||
257 | } else { |
||
258 | $option_prefix = "wordpoints_{$this->type}_{$this->slug}"; |
||
259 | } |
||
260 | |||
261 | return "{$option_prefix}_installed_sites"; |
||
262 | } |
||
263 | |||
264 | /** |
||
265 | * Gets the IDs of all sites on the network. |
||
266 | * |
||
267 | * @since 2.4.0 |
||
268 | * |
||
269 | * @return array The IDs of all sites on the network. |
||
270 | */ |
||
271 | protected function get_all_site_ids() { |
||
272 | |||
273 | return get_sites( |
||
274 | array( |
||
275 | 'fields' => 'ids', |
||
276 | 'network_id' => get_current_network_id(), |
||
277 | 'number' => 0, |
||
278 | ) |
||
279 | ); |
||
280 | } |
||
281 | |||
282 | /** |
||
283 | * Validates a list of site IDs against the database. |
||
284 | * |
||
285 | * @since 2.4.0 |
||
286 | * |
||
287 | * @param array $site_ids The site IDs to validate. |
||
288 | * |
||
289 | * @return int[] The validated site IDs. |
||
290 | */ |
||
291 | View Code Duplication | protected function validate_site_ids( $site_ids ) { |
|
292 | |||
293 | if ( empty( $site_ids ) || ! is_array( $site_ids ) ) { |
||
294 | return array(); |
||
295 | } |
||
296 | |||
297 | $site_ids = get_sites( |
||
298 | array( |
||
299 | 'fields' => 'ids', |
||
300 | 'network_id' => get_current_network_id(), |
||
301 | 'number' => 0, |
||
302 | 'site__in' => $site_ids, |
||
303 | ) |
||
304 | ); |
||
305 | |||
306 | return $site_ids; |
||
307 | } |
||
308 | |||
309 | /** |
||
310 | * @since 2.4.0 |
||
311 | */ |
||
312 | public function add_installed_site_id( $id = null ) { |
||
313 | |||
314 | if ( empty( $id ) ) { |
||
315 | $id = get_current_blog_id(); |
||
316 | } |
||
317 | |||
318 | $option_name = $this->get_installed_site_ids_option_name(); |
||
319 | |||
320 | $sites = wordpoints_get_array_option( $option_name, 'site' ); |
||
321 | |||
322 | if ( ! in_array( $id, $sites, true ) ) { |
||
323 | |||
324 | $sites[] = $id; |
||
325 | |||
326 | update_site_option( $option_name, $sites ); |
||
327 | } |
||
328 | } |
||
329 | |||
330 | /** |
||
331 | * @since 2.4.0 |
||
332 | */ |
||
333 | public function delete_installed_site_ids() { |
||
334 | delete_site_option( $this->get_installed_site_ids_option_name() ); |
||
335 | } |
||
336 | |||
337 | /** |
||
338 | * @since 2.4.0 |
||
339 | */ |
||
340 | public function get_install_routines() { |
||
341 | |||
342 | return array_merge_recursive( |
||
343 | $this->get_db_tables_install_routines() |
||
344 | , $this->get_custom_caps_install_routines() |
||
345 | ); |
||
346 | } |
||
347 | |||
348 | /** |
||
349 | * Gets the install routines for database tables for this entity. |
||
350 | * |
||
351 | * @since 2.4.0 |
||
352 | * |
||
353 | * @return WordPoints_Installer_DB_Tables[] Routines for installing DB tables. |
||
354 | */ |
||
355 | protected function get_db_tables_install_routines() { |
||
356 | |||
357 | $routines = array(); |
||
358 | |||
359 | $db_tables = wordpoints_map_context_shortcuts( $this->get_db_tables() ); |
||
360 | |||
361 | View Code Duplication | if ( isset( $db_tables['single'] ) ) { |
|
362 | $routines['single'][] = new WordPoints_Installer_DB_Tables( |
||
363 | $db_tables['single'] |
||
364 | , 'base' |
||
365 | ); |
||
366 | } |
||
367 | |||
368 | if ( isset( $db_tables['site'] ) ) { |
||
369 | $routines['site'][] = new WordPoints_Installer_DB_Tables( |
||
370 | $db_tables['site'] |
||
371 | ); |
||
372 | } |
||
373 | |||
374 | View Code Duplication | if ( isset( $db_tables['network'] ) ) { |
|
375 | $routines['network'][] = new WordPoints_Installer_DB_Tables( |
||
376 | $db_tables['network'] |
||
377 | , 'base' |
||
378 | ); |
||
379 | } |
||
380 | |||
381 | return $routines; |
||
382 | } |
||
383 | |||
384 | /** |
||
385 | * Gets database tables for this entity. |
||
386 | * |
||
387 | * An array of arrays, where each sub-array holds the tables for a particular |
||
388 | * context. Within each sub-array, the value of each element is the DB field |
||
389 | * schema for a table (i.e., the part of the CREATE TABLE query within the main |
||
390 | * parentheses), and the keys are the table names. The base DB prefix will be |
||
391 | * prepended to table names for $single and $network, while $site tables will be |
||
392 | * prepended with blog prefix instead. |
||
393 | * |
||
394 | * @since 2.4.0 |
||
395 | * |
||
396 | * @return string[][] $db_tables { |
||
397 | * @type string[] $single Tables for a single site (non-multisite) install. |
||
398 | * @type string[] $site Tables for each site in a multisite network. |
||
399 | * @type string[] $network Tables for a multisite network. |
||
400 | * @type string[] $local Tables for $single and $site. |
||
401 | * @type string[] $global Tables for $single and $network. |
||
402 | * @type string[] $universal Tables for $single, $site, and $network. |
||
403 | * } |
||
404 | */ |
||
405 | protected function get_db_tables() { |
||
406 | return array(); |
||
407 | } |
||
408 | |||
409 | /** |
||
410 | * Gets install routines for custom capabilities for this entity. |
||
411 | * |
||
412 | * @since 2.4.0 |
||
413 | * |
||
414 | * @return WordPoints_Installer_Caps[][] Custom caps installers. |
||
415 | */ |
||
416 | protected function get_custom_caps_install_routines() { |
||
417 | |||
418 | $caps = $this->get_custom_caps(); |
||
419 | |||
420 | if ( empty( $caps ) ) { |
||
421 | return array(); |
||
422 | } |
||
423 | |||
424 | return array( |
||
425 | 'site' => array( new WordPoints_Installer_Caps( $caps ) ), |
||
426 | 'single' => array( new WordPoints_Installer_Caps( $caps ) ), |
||
427 | ); |
||
428 | } |
||
429 | |||
430 | /** |
||
431 | * Gets the custom capabilities used by this entity. |
||
432 | * |
||
433 | * The function should return an array of capabilities of the format processed |
||
434 | * by {@see wordpoints_add_custom_caps()}. |
||
435 | * |
||
436 | * @since 2.4.0 |
||
437 | * |
||
438 | * @return string[] The custom caps (keys) and their corresponding core caps |
||
439 | * (values). |
||
440 | */ |
||
441 | protected function get_custom_caps() { |
||
442 | return array(); |
||
443 | } |
||
444 | |||
445 | /** |
||
446 | * @since 2.4.0 |
||
447 | */ |
||
448 | public function get_update_routine_factories() { |
||
449 | return array(); |
||
450 | } |
||
451 | |||
452 | /** |
||
453 | * @since 2.4.0 |
||
454 | */ |
||
455 | public function get_uninstall_routines() { |
||
488 | } |
||
489 | |||
490 | /** |
||
491 | * Gets a list of factories to create the uninstall routines for this entity. |
||
492 | * |
||
493 | * @since 2.4.0 |
||
494 | * |
||
495 | * @return object[] Uninstall routine factories. |
||
496 | */ |
||
497 | protected function get_uninstall_routine_factories() { |
||
518 | } |
||
519 | } |
||
520 | |||
521 | // EOF |
||
522 |
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.