Completed
Pull Request — master (#10259)
by Mike
13:41
created

WC_Abstract_Legacy_Order   B

Complexity

Total Complexity 53

Size/Duplication

Total Lines 300
Duplicated Lines 7 %

Coupling/Cohesion

Components 1
Dependencies 3
Metric Value
wmc 53
lcom 1
cbo 3
dl 21
loc 300
rs 7.4757

17 Methods

Rating   Name   Duplication   Size   Complexity  
A set_address() 0 8 3
C set_total() 0 40 8
A __isset() 0 5 3
C __get() 0 71 21
A get_item_meta() 0 4 1
A get_item_meta_array() 0 5 1
A expand_item_meta() 0 4 1
A init() 10 10 4
A get_order() 11 11 3
A populate() 0 4 1
A cancel_order() 0 5 1
A record_product_sales() 0 4 1
A increase_coupon_usage_counts() 0 4 1
A decrease_coupon_usage_counts() 0 4 1
A reduce_order_stock() 0 4 1
A send_stock_notifications() 0 3 1
A email_order_items_table() 0 3 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

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 Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like WC_Abstract_Legacy_Order 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 WC_Abstract_Legacy_Order, and based on these observations, apply Extract Interface, too.

1
<?php
1 ignored issue
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 18 and the first side effect is on line 3.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
if ( ! defined( 'ABSPATH' ) ) {
3
	exit;
4
}
5
6
/**
7
 * Legacy Abstract Order
8
 *
9
 * Legacy and deprecated functions are here to keep the WC_Abstract_Order clean.
10
 * This class will be removed in future versions.
11
 *
12
 * @class       WC_Abstract_Order
13
 * @version     2.6.0
14
 * @package     WooCommerce/Classes
15
 * @category    Class
16
 * @author      WooThemes
17
 */
18
abstract class WC_Abstract_Legacy_Order {
19
20
    /**
21
     * Set the customer address.
22
     * @since 2.2.0
23
     * @param array $address Address data.
24
     * @param string $type billing or shipping.
25
     */
26
    public function set_address( $address, $type = 'billing' ) {
27
        foreach ( $address as $key => $value ) {
28
            update_post_meta( $this->get_id(), "_{$type}_" . $key, $value );
29
            if ( is_callable( array( $this, "set_{$type}_{$key}" ) ) ) {
30
                $this->{"set_{$type}_{$key}"}( $value );
31
            }
32
        }
33
    }
34
35
    /**
36
     * Set an order total.
37
     * @since 2.2.0
38
     * @param float $amount
39
     * @param string $total_type
40
     * @return bool
41
     */
42
    public function set_total( $amount, $total_type = 'total' ) {
43
        if ( ! in_array( $total_type, array( 'shipping', 'tax', 'shipping_tax', 'total', 'cart_discount', 'cart_discount_tax' ) ) ) {
44
            return false;
45
        }
46
47
        switch ( $total_type ) {
48
            case 'total' :
49
                $amount = wc_format_decimal( $amount, wc_get_price_decimals() );
50
                $this->set_order_total( $amount );
51
                update_post_meta( $this->get_id(), '_order_total', $amount );
52
                break;
53
            case 'cart_discount' :
54
                $amount = wc_format_decimal( $amount );
55
                $this->set_discount_total( $amount );
56
                update_post_meta( $this->get_id(), '_cart_discount', $amount );
57
                break;
58
            case 'cart_discount_tax' :
59
                $amount = wc_format_decimal( $amount );
60
                $this->set_discount_tax( $amount );
61
                update_post_meta( $this->get_id(), '_cart_discount_tax', $amount );
62
                break;
63
            case 'shipping' :
64
                $amount = wc_format_decimal( $amount );
65
                $this->set_shipping_total( $amount );
66
                update_post_meta( $this->get_id(), '_order_shipping', $amount );
67
                break;
68
            case 'shipping_tax' :
69
                $amount = wc_format_decimal( $amount );
70
                $this->set_shipping_tax( $amount );
71
                update_post_meta( $this->get_id(), '_order_shipping_tax', $amount );
72
                break;
73
            case 'tax' :
74
                $amount = wc_format_decimal( $amount );
75
                $this->set_cart_tax( $amount );
76
                update_post_meta( $this->get_id(), '_order_tax', $amount );
77
                break;
78
        }
79
80
        return true;
81
    }
82
83
    /**
84
     * Magic __isset method for backwards compatibility.
85
     * @param string $key
86
     * @return bool
87
     */
88
    public function __isset( $key ) {
89
        // Legacy properties which could be accessed directly in the past.
90
        $legacy_props = array( 'completed_date', 'id', 'order_type', 'post', 'status', 'post_status', 'customer_note', 'customer_message', 'user_id', 'customer_user', 'prices_include_tax', 'tax_display_cart', 'display_totals_ex_tax', 'display_cart_ex_tax', 'order_date', 'modified_date', 'cart_discount', 'cart_discount_tax', 'order_shipping', 'order_shipping_tax', 'order_total', 'order_tax', 'billing_first_name', 'billing_last_name', 'billing_company', 'billing_address_1', 'billing_address_2', 'billing_city', 'billing_state', 'billing_postcode', 'billing_country', 'billing_phone', 'billing_email', 'shipping_first_name', 'shipping_last_name', 'shipping_company', 'shipping_address_1', 'shipping_address_2', 'shipping_city', 'shipping_state', 'shipping_postcode', 'shipping_country', 'customer_ip_address', 'customer_user_agent', 'payment_method_title', 'payment_method', 'order_currency' );
91
        return $this->get_id() ? ( in_array( $key, $legacy_props ) || metadata_exists( 'post', $this->get_id(), '_' . $key ) ) : false;
92
    }
93
94
    /**
95
     * Magic __get method for backwards compatibility.
96
     * @param string $key
97
     * @return mixed
98
     */
99
    public function __get( $key ) {
100
        /**
101
         * Maps legacy vars to new getters.
102
         */
103
        if ( 'completed_date' === $key ) {
104
            _doing_it_wrong( $key, 'Order properties should not be accessed directly.', '2.6' );
105
            return $this->get_date_completed();
106
		} elseif ( 'paid_date' === $key ) {
107
            _doing_it_wrong( $key, 'Order properties should not be accessed directly.', '2.6' );
108
            return $this->get_date_paid();
109
        } elseif ( 'modified_date' === $key ) {
110
            _doing_it_wrong( $key, 'Order properties should not be accessed directly.', '2.6' );
111
            return $this->get_date_modified();
112
        } elseif ( 'order_date' === $key ) {
113
            _doing_it_wrong( $key, 'Order properties should not be accessed directly.', '2.6' );
114
            return $this->get_date_created();
115
        } elseif ( 'id' === $key ) {
116
            _doing_it_wrong( $key, 'Order properties should not be accessed directly.', '2.6' );
117
            return $this->get_id();
118
		} elseif ( 'post' === $key ) {
119
            _doing_it_wrong( $key, 'Order properties should not be accessed directly.', '2.6' );
120
            return get_post( $this->get_id() );
121
		} elseif ( 'status' === $key || 'post_status' === $key ) {
122
            _doing_it_wrong( $key, 'Order properties should not be accessed directly.', '2.6' );
123
            return $this->get_status();
124
		} elseif ( 'customer_message' === $key || 'customer_note' === $key ) {
125
            _doing_it_wrong( $key, 'Order properties should not be accessed directly.', '2.6' );
126
            return $this->get_customer_note();
127
		} elseif ( in_array( $key, array( 'user_id', 'customer_user' ) ) ) {
128
            _doing_it_wrong( $key, 'Order properties should not be accessed directly.', '2.6' );
129
            return $this->get_customer_id();
130
		} elseif ( 'tax_display_cart' === $key ) {
131
            _doing_it_wrong( $key, 'Order properties should not be accessed directly.', '2.6' );
132
			return get_option( 'woocommerce_tax_display_cart' );
133
		} elseif ( 'display_totals_ex_tax' === $key ) {
134
            _doing_it_wrong( $key, 'Order properties should not be accessed directly.', '2.6' );
135
			return 'excl' === get_option( 'woocommerce_tax_display_cart' );
136
		} elseif ( 'display_cart_ex_tax' === $key ) {
137
            _doing_it_wrong( $key, 'Order properties should not be accessed directly.', '2.6' );
138
			return 'excl' === get_option( 'woocommerce_tax_display_cart' );
139
        } elseif ( 'cart_discount' === $key ) {
140
            _doing_it_wrong( $key, 'Order properties should not be accessed directly.', '2.6' );
141
			return $this->get_discount();
0 ignored issues
show
Bug introduced by
The method get_discount() does not seem to exist on object<WC_Abstract_Legacy_Order>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
142
        } elseif ( 'cart_discount_tax' === $key ) {
143
            _doing_it_wrong( $key, 'Order properties should not be accessed directly.', '2.6' );
144
			return $this->get_discount_tax();
145
        } elseif ( 'order_tax' === $key ) {
146
            _doing_it_wrong( $key, 'Order properties should not be accessed directly.', '2.6' );
147
			return $this->get_cart_tax();
148
        } elseif ( 'order_shipping_tax' === $key ) {
149
            _doing_it_wrong( $key, 'Order properties should not be accessed directly.', '2.6' );
150
            return $this->get_shipping_tax();
151
        } elseif ( 'order_shipping' === $key ) {
152
            _doing_it_wrong( $key, 'Order properties should not be accessed directly.', '2.6' );
153
            return $this->get_shipping();
0 ignored issues
show
Bug introduced by
The method get_shipping() does not seem to exist on object<WC_Abstract_Legacy_Order>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
154
        /**
155
         * Map vars to getters with warning.
156
         */
157
	 	} elseif ( is_callable( array( $this, "get_{$key}" ) ) ) {
158
			_doing_it_wrong( $key, 'Order properties should not be accessed directly Use get_' . $key . '().', '2.6' );
159
            return $this->{"get_{$key}"}();
160
        /**
161
         * Handle post meta
162
         */
163
        } else {
164
            _doing_it_wrong( $key, 'Meta should not be accessed directly. Use WC_Order::get_order_meta( $key )', '2.6' );
165
			$value = get_post_meta( $this->get_id(), '_' . $key, true );
166
		}
167
168
        return $value;
169
    }
170
171
    /**
172
     * Get order item meta.
173
     * @deprecated 2.6.0
174
     * @param mixed $order_item_id
175
     * @param string $key (default: '')
176
     * @param bool $single (default: false)
177
     * @return array|string
178
     */
179
    public function get_item_meta( $order_item_id, $key = '', $single = false ) {
180
        _deprecated_function( 'get_item_meta', '2.6', 'wc_get_order_item_meta' );
181
        return get_metadata( 'order_item', $order_item_id, $key, $single );
182
    }
183
184
    /**
185
     * Get all item meta data in array format in the order it was saved. Does not group meta by key like get_item_meta().
186
     *
187
     * @param mixed $order_item_id
188
     * @return array of objects
189
     */
190
    public function get_item_meta_array( $order_item_id ) {
191
        _deprecated_function( 'get_item_meta_array', '2.6', 'WC_Order_Item::get_meta_data()' );
192
        $item = $this->get_item( $order_item_id );
0 ignored issues
show
Bug introduced by
The method get_item() does not exist on WC_Abstract_Legacy_Order. Did you maybe mean get_item_meta()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
193
        return $item->get_meta_data();
194
    }
195
196
    /**
197
     * Expand item meta into the $item array.
198
     * @deprecated 2.6.0 Item meta no longer expanded due to new order item
199
     *        classes. This function now does nothing to avoid data breakage.
200
     * @since 2.4.0
201
     * @param array $item before expansion.
202
     * @return array
203
     */
204
    public function expand_item_meta( $item ) {
205
        _deprecated_function( 'expand_item_meta', '2.6', '' );
206
        return $item;
207
    }
208
209
	/**
210
     * Load the order object. Called from the constructor.
211
     * @deprecated 2.6.0 Logic moved to constructor
212
     * @param int|object|WC_Order $order Order to init.
213
     */
214 View Code Duplication
    protected function init( $order ) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
215
		_deprecated_function( 'init', '2.6', 'Logic moved to constructor' );
216
        if ( is_numeric( $order ) ) {
217
            $this->read( $order );
218
        } elseif ( $order instanceof WC_Order ) {
219
            $this->read( absint( $order->get_id() ) );
220
        } elseif ( isset( $order->ID ) ) {
221
            $this->read( absint( $order->ID ) );
222
        }
223
    }
224
225
    /**
226
     * Gets an order from the database.
227
     * @deprecated 2.6
228
     * @param int $id (default: 0).
229
     * @return bool
230
     */
231 View Code Duplication
    public function get_order( $id = 0 ) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
232
        _deprecated_function( 'get_order', '2.6', 'read' );
233
        if ( ! $id ) {
234
            return false;
235
        }
236
        if ( $result = get_post( $id ) ) {
237
            $this->populate( $result );
0 ignored issues
show
Deprecated Code introduced by
The method WC_Abstract_Legacy_Order::populate() has been deprecated with message: 2.6

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
238
            return true;
239
        }
240
        return false;
241
    }
242
243
    /**
244
     * Populates an order from the loaded post data.
245
     * @deprecated 2.6
246
     * @param mixed $result
247
     */
248
    public function populate( $result ) {
249
        _deprecated_function( 'populate', '2.6', 'read' );
250
        $this->read( $result->ID );
251
    }
252
253
	/**
254
     * Cancel the order and restore the cart (before payment).
255
     * @deprecated 2.6.0 Moved to event handler.
256
     * @param string $note (default: '') Optional note to add.
257
     */
258
    public function cancel_order( $note = '' ) {
259
		_deprecated_function( 'cancel_order', '2.6', 'update_status' );
260
        WC()->session->set( 'order_awaiting_payment', false );
261
        $this->update_status( 'cancelled', $note );
262
    }
263
264
	/**
265
     * Record sales.
266
     * @deprecated 2.6.0
267
     */
268
    public function record_product_sales() {
269
		_deprecated_function( 'record_product_sales', '2.6', 'wc_update_total_sales_counts' );
270
		wc_update_total_sales_counts( $this->get_id() );
271
    }
272
273
	/**
274
     * Increase applied coupon counts.
275
     * @deprecated 2.6.0
276
     */
277
    public function increase_coupon_usage_counts() {
278
		_deprecated_function( 'increase_coupon_usage_counts', '2.6', 'wc_update_coupon_usage_counts' );
279
		wc_update_coupon_usage_counts( $this->get_id() );
280
    }
281
282
    /**
283
     * Decrease applied coupon counts.
284
     * @deprecated 2.6.0
285
     */
286
    public function decrease_coupon_usage_counts() {
287
		_deprecated_function( 'decrease_coupon_usage_counts', '2.6', 'wc_update_coupon_usage_counts' );
288
		wc_update_coupon_usage_counts( $this->get_id() );
289
    }
290
291
	/**
292
     * Reduce stock levels for all line items in the order.
293
	 * @deprecated 2.6.0
294
     */
295
    public function reduce_order_stock() {
296
        _deprecated_function( 'reduce_order_stock', '2.6', 'wc_reduce_stock_levels' );
297
		wc_reduce_stock_levels( $this->get_id() );
298
    }
299
300
	/**
301
     * Send the stock notifications.
302
	 * @deprecated 2.6.0 No longer needs to be called directly.
303
     */
304
    public function send_stock_notifications( $product, $new_stock, $qty_ordered ) {
0 ignored issues
show
Unused Code introduced by
The parameter $product is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $new_stock is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $qty_ordered is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
305
        _deprecated_function( 'send_stock_notifications', '2.6' );
306
    }
307
308
	/**
309
	 * Output items for display in html emails.
310
	 * @deprecated 2.6.0 Moved to template functions.
311
	 * @param array $args Items args.
312
	 * @return string
313
	 */
314
	public function email_order_items_table( $args = array() ) {
315
		return wc_get_email_order_items( $this, $args );
0 ignored issues
show
Compatibility introduced by
$this of type object<WC_Abstract_Legacy_Order> is not a sub-type of object<WC_Order>. It seems like you assume a child class of the class WC_Abstract_Legacy_Order to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
316
	}
317
}
318