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 |
||
23 | class WC_REST_Order_Refunds_Controller extends WC_REST_Posts_Controller { |
||
24 | |||
25 | /** |
||
26 | * Endpoint namespace. |
||
27 | * |
||
28 | * @var string |
||
29 | */ |
||
30 | protected $namespace = 'wc/v1'; |
||
31 | |||
32 | /** |
||
33 | * Route base. |
||
34 | * |
||
35 | * @var string |
||
36 | */ |
||
37 | protected $rest_base = 'orders/(?P<order_id>[\d]+)/refunds'; |
||
38 | |||
39 | /** |
||
40 | * Post type. |
||
41 | * |
||
42 | * @var string |
||
43 | */ |
||
44 | protected $post_type = 'shop_order_refund'; |
||
45 | |||
46 | /** |
||
47 | * Order refunds actions. |
||
48 | */ |
||
49 | public function __construct() { |
||
53 | |||
54 | /** |
||
55 | * Register the routes for order refunds. |
||
56 | */ |
||
57 | View Code Duplication | public function register_routes() { |
|
|
|||
58 | register_rest_route( $this->namespace, '/' . $this->rest_base, array( |
||
59 | array( |
||
60 | 'methods' => WP_REST_Server::READABLE, |
||
61 | 'callback' => array( $this, 'get_items' ), |
||
62 | 'permission_callback' => array( $this, 'get_items_permissions_check' ), |
||
63 | 'args' => $this->get_collection_params(), |
||
64 | ), |
||
65 | array( |
||
66 | 'methods' => WP_REST_Server::CREATABLE, |
||
67 | 'callback' => array( $this, 'create_item' ), |
||
68 | 'permission_callback' => array( $this, 'create_item_permissions_check' ), |
||
69 | 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), |
||
70 | ), |
||
71 | 'schema' => array( $this, 'get_public_item_schema' ), |
||
72 | ) ); |
||
73 | |||
74 | register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<id>[\d]+)', array( |
||
75 | array( |
||
76 | 'methods' => WP_REST_Server::READABLE, |
||
77 | 'callback' => array( $this, 'get_item' ), |
||
78 | 'permission_callback' => array( $this, 'get_item_permissions_check' ), |
||
79 | 'args' => array( |
||
80 | 'context' => $this->get_context_param( array( 'default' => 'view' ) ), |
||
81 | ), |
||
82 | ), |
||
83 | array( |
||
84 | 'methods' => WP_REST_Server::DELETABLE, |
||
85 | 'callback' => array( $this, 'delete_item' ), |
||
86 | 'permission_callback' => array( $this, 'delete_item_permissions_check' ), |
||
87 | 'args' => array( |
||
88 | 'force' => array( |
||
89 | 'default' => false, |
||
90 | 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), |
||
91 | ), |
||
92 | 'reassign' => array(), |
||
93 | ), |
||
94 | ), |
||
95 | 'schema' => array( $this, 'get_public_item_schema' ), |
||
96 | ) ); |
||
97 | } |
||
98 | |||
99 | /** |
||
100 | * Prepare a single order refund output for response. |
||
101 | * |
||
102 | * @param WP_Post $post Post object. |
||
103 | * @param WP_REST_Request $request Request object. |
||
104 | * @return WP_REST_Response $data |
||
105 | */ |
||
106 | public function prepare_item_for_response( $post, $request ) { |
||
219 | |||
220 | /** |
||
221 | * Prepare links for the request. |
||
222 | * |
||
223 | * @param WC_Order_Refund $refund Comment object. |
||
224 | * @return array Links for the given order refund. |
||
225 | */ |
||
226 | View Code Duplication | protected function prepare_links( $refund ) { |
|
243 | |||
244 | /** |
||
245 | * Query args. |
||
246 | * |
||
247 | * @param array $args |
||
248 | * @param WP_REST_Request $request |
||
249 | * @return array |
||
250 | */ |
||
251 | public function query_args( $args, $request ) { |
||
257 | |||
258 | /** |
||
259 | * Create a single item. |
||
260 | * |
||
261 | * @param WP_REST_Request $request Full details about the request. |
||
262 | * @return WP_Error|WP_REST_Response |
||
263 | */ |
||
264 | public function create_item( $request ) { |
||
265 | if ( ! empty( $request['id'] ) ) { |
||
266 | return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); |
||
267 | } |
||
268 | |||
269 | $order_data = get_post( (int) $request['order_id'] ); |
||
270 | |||
271 | if ( empty( $order_data ) ) { |
||
272 | return new WP_Error( 'woocommerce_rest_invalid_order', __( 'Order is invalid', 'woocommerce' ), 400 ); |
||
273 | } |
||
274 | |||
275 | if ( 0 > $request['amount'] ) { |
||
276 | return new WP_Error( 'woocommerce_rest_invalid_order_refund', __( 'Refund amount must be greater than zero.', 'woocommerce' ), 400 ); |
||
277 | } |
||
278 | |||
279 | $api_refund = is_bool( $request['api_refund'] ) ? $request['api_refund'] : true; |
||
280 | |||
281 | $data = array( |
||
282 | 'order_id' => $order_data->ID, |
||
283 | 'amount' => $request['amount'], |
||
284 | 'line_items' => $request['line_items'], |
||
285 | ); |
||
286 | |||
287 | // Create the refund. |
||
288 | $refund = wc_create_refund( $data ); |
||
289 | |||
290 | if ( ! $refund ) { |
||
291 | return new WP_Error( 'woocommerce_rest_cannot_create_order_refund', __( 'Cannot create order refund, please try again.', 'woocommerce' ), 500 ); |
||
292 | } |
||
293 | |||
294 | // Refund via API. |
||
295 | if ( $api_refund ) { |
||
296 | if ( WC()->payment_gateways() ) { |
||
297 | $payment_gateways = WC()->payment_gateways->payment_gateways(); |
||
298 | } |
||
299 | |||
300 | $order = wc_get_order( $order_data ); |
||
301 | |||
302 | if ( isset( $payment_gateways[ $order->payment_method ] ) && $payment_gateways[ $order->payment_method ]->supports( 'refunds' ) ) { |
||
303 | $result = $payment_gateways[ $order->payment_method ]->process_refund( $order_id, $refund->get_refund_amount(), $refund->get_refund_reason() ); |
||
304 | |||
305 | View Code Duplication | if ( is_wp_error( $result ) ) { |
|
306 | return $result; |
||
307 | } elseif ( ! $result ) { |
||
308 | return new WP_Error( 'woocommerce_rest_create_order_refund_api_failed', __( 'An error occurred while attempting to create the refund using the payment gateway API.', 'woocommerce' ), 500 ); |
||
309 | } |
||
310 | } |
||
311 | } |
||
312 | |||
313 | $post = get_post( $refund->id ); |
||
314 | $this->update_additional_fields_for_object( $post, $request ); |
||
315 | |||
316 | /** |
||
317 | * Fires after a single item is created or updated via the REST API. |
||
318 | * |
||
319 | * @param object $post Inserted object (not a WP_Post object). |
||
320 | * @param WP_REST_Request $request Request object. |
||
321 | * @param boolean $creating True when creating item, false when updating. |
||
322 | */ |
||
323 | do_action( "woocommerce_rest_insert_{$this->post_type}", $post, $request, true ); |
||
324 | |||
325 | $request->set_param( 'context', 'edit' ); |
||
326 | $response = $this->prepare_item_for_response( $post, $request ); |
||
327 | $response = rest_ensure_response( $response ); |
||
328 | $response->set_status( 201 ); |
||
329 | $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $post->ID ) ) ); |
||
330 | |||
331 | return $response; |
||
332 | } |
||
333 | |||
334 | /** |
||
335 | * Get the Order's schema, conforming to JSON Schema. |
||
336 | * |
||
337 | * @return array |
||
338 | */ |
||
339 | public function get_item_schema() { |
||
496 | |||
497 | /** |
||
498 | * Get the query params for collections. |
||
499 | * |
||
500 | * @return array |
||
501 | */ |
||
502 | View Code Duplication | public function get_collection_params() { |
|
515 | } |
||
516 |
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.