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 |
||
11 | class WC_CLI_Report extends WC_CLI_Command { |
||
12 | |||
13 | /** |
||
14 | * List reports. |
||
15 | * |
||
16 | * ## OPTIONS |
||
17 | * |
||
18 | * [--format=<format>] |
||
19 | * : Acceptec values: table, csv, json, count, ids. Default: table. |
||
20 | * |
||
21 | * ## EXAMPLES |
||
22 | * |
||
23 | * wp wc report list |
||
24 | * |
||
25 | * @subcommand list |
||
26 | * @since 2.5.0 |
||
27 | */ |
||
28 | public function list_( $__, $assoc_args ) { |
||
43 | |||
44 | /** |
||
45 | * View sales report. |
||
46 | * |
||
47 | * ## OPTIONS |
||
48 | * |
||
49 | * [--field=<field>] |
||
50 | * : Instead of returning the whole report fields, returns the value of a single fields. |
||
51 | * |
||
52 | * [--fields=<fields>] |
||
53 | * : Get a specific subset of the report's fields. |
||
54 | * |
||
55 | * [--format=<format>] |
||
56 | * : Accepted values: table, json, csv. Default: table. |
||
57 | * |
||
58 | * [--period=<period>] |
||
59 | * : The supported periods are: week, month, last_month, and year. If invalid |
||
60 | * period is supplied, week is used. If period is not specified, the current |
||
61 | * day is used. |
||
62 | * |
||
63 | * [--date_min] |
||
64 | * : Return sales for a specific start date. The date need to be in the YYYY-MM-AA format. |
||
65 | * |
||
66 | * [--date_max] |
||
67 | * : Return sales for a specific end date. The dates need to be in the YYYY-MM-AA format. |
||
68 | * |
||
69 | * [--limit] |
||
70 | * : Limit report result. Default: 12. |
||
71 | * |
||
72 | * ## AVAILABLE FIELDS |
||
73 | * |
||
74 | * These fields are available for get command: |
||
75 | * |
||
76 | * * total_sales |
||
77 | * * average_sales |
||
78 | * * total_orders |
||
79 | * * total_items |
||
80 | * * total_tax |
||
81 | * * total_shipping |
||
82 | * * total_discount |
||
83 | * * totals_grouped_by |
||
84 | * * totals |
||
85 | * * total_customers |
||
86 | * |
||
87 | * ## EXAMPLES |
||
88 | * |
||
89 | * wp wc report sales |
||
90 | * |
||
91 | * wp wc report sales --period=last_month |
||
92 | * |
||
93 | * @since 2.5.0 |
||
94 | */ |
||
95 | public function sales( $__, $assoc_args ) { |
||
218 | |||
219 | /** |
||
220 | * View report of top sellers. |
||
221 | * |
||
222 | * ## OPTIONS |
||
223 | * |
||
224 | * [--<field>=<value>] |
||
225 | * : Filter report based on report property. |
||
226 | * |
||
227 | * [--field=<field>] |
||
228 | * : Prints the value of a single field for each seller. |
||
229 | * |
||
230 | * [--fields=<fields>] |
||
231 | * : Limit the output to specific report fields. |
||
232 | * |
||
233 | * [--format=<format>] |
||
234 | * : Acceptec values: table, csv, json, count, ids. Default: table. |
||
235 | * |
||
236 | * [--period=<period>] |
||
237 | * : The supported periods are: week, month, last_month, and year. If invalid |
||
238 | * period is supplied, week is used. If period is not specified, the current |
||
239 | * day is used. |
||
240 | * |
||
241 | * [--date_min] |
||
242 | * : Return sales for a specific start date. The date need to be in the YYYY-MM-AA format. |
||
243 | * |
||
244 | * [--date_max] |
||
245 | * : Return sales for a specific end date. The dates need to be in the YYYY-MM-AA format. |
||
246 | * |
||
247 | * [--limit] |
||
248 | * : Limit report result. Default: 12. |
||
249 | * |
||
250 | * ## AVAILABLE FIELDS |
||
251 | * |
||
252 | * These fields will be displayed by default for each row: |
||
253 | * |
||
254 | * * title |
||
255 | * * product_id |
||
256 | * * quantity |
||
257 | * |
||
258 | * ## EXAMPLES |
||
259 | * |
||
260 | * wp wc report top_sellers |
||
261 | * |
||
262 | * wp wc report top_sellers --period=last_month |
||
263 | * |
||
264 | * @since 2.5.0 |
||
265 | */ |
||
266 | public function top_sellers( $__, $assoc_args ) { |
||
267 | $reporter = $this->get_reporter( $assoc_args ); |
||
268 | $top_sellers = $reporter->get_order_report_data( array( |
||
269 | 'data' => array( |
||
270 | '_product_id' => array( |
||
271 | 'type' => 'order_item_meta', |
||
272 | 'order_item_type' => 'line_item', |
||
273 | 'function' => '', |
||
274 | 'name' => 'product_id' |
||
275 | ), |
||
276 | '_qty' => array( |
||
277 | 'type' => 'order_item_meta', |
||
278 | 'order_item_type' => 'line_item', |
||
279 | 'function' => 'SUM', |
||
280 | 'name' => 'order_item_qty' |
||
281 | ) |
||
282 | ), |
||
283 | 'order_by' => 'order_item_qty DESC', |
||
284 | 'group_by' => 'product_id', |
||
285 | 'limit' => isset( $assoc_args['limit'] ) ? absint( $assoc_args['limit'] ) : 12, |
||
286 | 'query_type' => 'get_results', |
||
287 | 'filter_range' => true, |
||
288 | ) ); |
||
289 | |||
290 | $top_sellers_data = array(); |
||
291 | View Code Duplication | foreach ( $top_sellers as $top_seller ) { |
|
|
|||
292 | $product = wc_get_product( $top_seller->product_id ); |
||
293 | |||
294 | if ( $product ) { |
||
295 | $top_sellers_data[] = array( |
||
296 | 'title' => $product->get_title(), |
||
297 | 'product_id' => $top_seller->product_id, |
||
298 | 'quantity' => $top_seller->order_item_qty, |
||
299 | ); |
||
300 | } |
||
301 | } |
||
302 | $top_sellers_data = apply_filters( 'woocommerce_cli_top_sellers_report', $top_sellers_data ); |
||
303 | |||
304 | $formatter = $this->get_formatter( $assoc_args ); |
||
305 | if ( 'ids' === $formatter->format ) { |
||
306 | $query_args['fields'] = 'ids'; |
||
307 | echo implode( ' ', wp_list_pluck( $top_sellers_data, 'product_id' ) ); |
||
308 | } else { |
||
309 | $formatter->display_items( $top_sellers_data ); |
||
310 | } |
||
311 | } |
||
312 | |||
313 | /** |
||
314 | * Setup the report object and parse any date filtering |
||
315 | * |
||
316 | * @since 2.5.0 |
||
317 | * @param array $assoc_args Arguments provided in when invoking the command |
||
318 | * @return WC_Report_Sales_By_Date |
||
319 | */ |
||
320 | private function get_reporter( $assoc_args ) { |
||
321 | |||
322 | include_once( WC()->plugin_path() . '/includes/admin/reports/class-wc-admin-report.php' ); |
||
323 | include_once( WC()->plugin_path() . '/includes/admin/reports/class-wc-report-sales-by-date.php' ); |
||
324 | |||
325 | $report = new WC_Report_Sales_By_Date(); |
||
326 | |||
327 | if ( empty( $assoc_args['period'] ) ) { |
||
328 | |||
329 | // custom date range |
||
330 | $assoc_args['period'] = 'custom'; |
||
331 | |||
332 | View Code Duplication | if ( ! empty( $assoc_args['date_min'] ) || ! empty( $assoc_args['date_max'] ) ) { |
|
333 | |||
334 | // overwrite _GET to make use of WC_Admin_Report::calculate_current_range() for custom date ranges |
||
335 | $_GET['start_date'] = $this->parse_datetime( $assoc_args['date_min'] ); |
||
336 | $_GET['end_date'] = isset( $assoc_args['date_max'] ) ? $this->parse_datetime( $assoc_args['date_max'] ) : null; |
||
337 | |||
338 | } else { |
||
339 | |||
340 | // default custom range to today |
||
341 | $_GET['start_date'] = $_GET['end_date'] = date( 'Y-m-d', current_time( 'timestamp' ) ); |
||
342 | } |
||
343 | |||
344 | } else { |
||
345 | |||
346 | // ensure period is valid |
||
347 | if ( ! in_array( $assoc_args['period'], array( 'week', 'month', 'last_month', 'year' ) ) ) { |
||
348 | $assoc_args['period'] = 'week'; |
||
349 | } |
||
350 | |||
351 | // TODO: change WC_Admin_Report class to use "week" instead, as it's more consistent with other periods |
||
352 | // allow "week" for period instead of "7day" |
||
353 | if ( 'week' === $assoc_args['period'] ) { |
||
354 | $assoc_args['period'] = '7day'; |
||
355 | } |
||
356 | } |
||
357 | |||
358 | $report->calculate_current_range( $assoc_args['period'] ); |
||
359 | |||
360 | return $report; |
||
361 | } |
||
362 | |||
363 | /** |
||
364 | * Get default format fields that will be used in `list` and `get` subcommands. |
||
365 | * |
||
366 | * @since 2.5.0 |
||
367 | * @return string |
||
368 | */ |
||
369 | protected function get_default_format_fields() { |
||
372 | } |
||
373 |
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.