1
|
|
|
<?php |
|
|
|
|
2
|
|
|
/** |
3
|
|
|
* WooCommerce Meta Boxes |
4
|
|
|
* |
5
|
|
|
* Sets up the write panels used by products and orders (custom post types). |
6
|
|
|
* |
7
|
|
|
* @author WooThemes |
8
|
|
|
* @category Admin |
9
|
|
|
* @package WooCommerce/Admin/Meta Boxes |
10
|
|
|
* @version 2.1.0 |
11
|
|
|
*/ |
12
|
|
|
|
13
|
|
|
if ( ! defined( 'ABSPATH' ) ) { |
14
|
|
|
exit; // Exit if accessed directly |
15
|
|
|
} |
16
|
|
|
|
17
|
|
|
/** |
18
|
|
|
* WC_Admin_Meta_Boxes. |
19
|
|
|
*/ |
20
|
|
|
class WC_Admin_Meta_Boxes { |
21
|
|
|
|
22
|
|
|
/** |
23
|
|
|
* Is meta boxes saved once? |
24
|
|
|
* |
25
|
|
|
* @var boolean |
26
|
|
|
*/ |
27
|
|
|
private static $saved_meta_boxes = false; |
28
|
|
|
|
29
|
|
|
/** |
30
|
|
|
* Meta box error messages. |
31
|
|
|
* |
32
|
|
|
* @var array |
33
|
|
|
*/ |
34
|
|
|
public static $meta_box_errors = array(); |
35
|
|
|
|
36
|
|
|
/** |
37
|
|
|
* Constructor. |
38
|
|
|
*/ |
39
|
|
|
public function __construct() { |
40
|
|
|
add_action( 'add_meta_boxes', array( $this, 'remove_meta_boxes' ), 10 ); |
41
|
|
|
add_action( 'add_meta_boxes', array( $this, 'rename_meta_boxes' ), 20 ); |
42
|
|
|
add_action( 'add_meta_boxes', array( $this, 'add_meta_boxes' ), 30 ); |
43
|
|
|
add_action( 'save_post', array( $this, 'save_meta_boxes' ), 1, 2 ); |
44
|
|
|
|
45
|
|
|
/** |
46
|
|
|
* Save Order Meta Boxes. |
47
|
|
|
* |
48
|
|
|
* In order: |
49
|
|
|
* Save the order items. |
50
|
|
|
* Save the order totals. |
51
|
|
|
* Save the order downloads. |
52
|
|
|
* Save order data - also updates status and sends out admin emails if needed. Last to show latest data. |
53
|
|
|
* Save actions - sends out other emails. Last to show latest data. |
54
|
|
|
*/ |
55
|
|
|
add_action( 'woocommerce_process_shop_order_meta', 'WC_Meta_Box_Order_Items::save', 10, 2 ); |
56
|
|
|
add_action( 'woocommerce_process_shop_order_meta', 'WC_Meta_Box_Order_Downloads::save', 30, 2 ); |
57
|
|
|
add_action( 'woocommerce_process_shop_order_meta', 'WC_Meta_Box_Order_Data::save', 40, 2 ); |
58
|
|
|
add_action( 'woocommerce_process_shop_order_meta', 'WC_Meta_Box_Order_Actions::save', 50, 2 ); |
59
|
|
|
|
60
|
|
|
// Save Product Meta Boxes |
61
|
|
|
add_action( 'woocommerce_process_product_meta', 'WC_Meta_Box_Product_Data::save', 10, 2 ); |
62
|
|
|
add_action( 'woocommerce_process_product_meta', 'WC_Meta_Box_Product_Images::save', 20, 2 ); |
63
|
|
|
|
64
|
|
|
// Save Coupon Meta Boxes |
65
|
|
|
add_action( 'woocommerce_process_shop_coupon_meta', 'WC_Meta_Box_Coupon_Data::save', 10, 2 ); |
66
|
|
|
|
67
|
|
|
// Save Rating Meta Boxes |
68
|
|
|
add_action( 'comment_edit_redirect', 'WC_Meta_Box_Order_Reviews::save', 1, 2 ); |
69
|
|
|
|
70
|
|
|
// Error handling (for showing errors from meta boxes on next page load) |
71
|
|
|
add_action( 'admin_notices', array( $this, 'output_errors' ) ); |
72
|
|
|
add_action( 'shutdown', array( $this, 'save_errors' ) ); |
73
|
|
|
} |
74
|
|
|
|
75
|
|
|
/** |
76
|
|
|
* Add an error message. |
77
|
|
|
* @param string $text |
78
|
|
|
*/ |
79
|
|
|
public static function add_error( $text ) { |
80
|
|
|
self::$meta_box_errors[] = $text; |
81
|
|
|
} |
82
|
|
|
|
83
|
|
|
/** |
84
|
|
|
* Save errors to an option. |
85
|
|
|
*/ |
86
|
|
|
public function save_errors() { |
87
|
|
|
update_option( 'woocommerce_meta_box_errors', self::$meta_box_errors ); |
88
|
|
|
} |
89
|
|
|
|
90
|
|
|
/** |
91
|
|
|
* Show any stored error messages. |
92
|
|
|
*/ |
93
|
|
|
public function output_errors() { |
94
|
|
|
$errors = maybe_unserialize( get_option( 'woocommerce_meta_box_errors' ) ); |
95
|
|
|
|
96
|
|
|
if ( ! empty( $errors ) ) { |
97
|
|
|
|
98
|
|
|
echo '<div id="woocommerce_errors" class="error notice is-dismissible">'; |
99
|
|
|
|
100
|
|
|
foreach ( $errors as $error ) { |
101
|
|
|
echo '<p>' . wp_kses_post( $error ) . '</p>'; |
102
|
|
|
} |
103
|
|
|
|
104
|
|
|
echo '</div>'; |
105
|
|
|
|
106
|
|
|
// Clear |
107
|
|
|
delete_option( 'woocommerce_meta_box_errors' ); |
108
|
|
|
} |
109
|
|
|
} |
110
|
|
|
|
111
|
|
|
/** |
112
|
|
|
* Add WC Meta boxes. |
113
|
|
|
*/ |
114
|
|
|
public function add_meta_boxes() { |
115
|
|
|
$screen = get_current_screen(); |
|
|
|
|
116
|
|
|
|
117
|
|
|
// Products |
118
|
|
|
add_meta_box( 'postexcerpt', __( 'Product Short Description', 'woocommerce' ), 'WC_Meta_Box_Product_Short_Description::output', 'product', 'normal' ); |
119
|
|
|
add_meta_box( 'woocommerce-product-data', __( 'Product Data', 'woocommerce' ), 'WC_Meta_Box_Product_Data::output', 'product', 'normal', 'high' ); |
120
|
|
|
add_meta_box( 'woocommerce-product-images', __( 'Product Gallery', 'woocommerce' ), 'WC_Meta_Box_Product_Images::output', 'product', 'side', 'low' ); |
121
|
|
|
remove_meta_box( 'commentsdiv', 'product', 'normal' ); |
122
|
|
|
|
123
|
|
|
// Orders |
124
|
|
|
foreach ( wc_get_order_types( 'order-meta-boxes' ) as $type ) { |
125
|
|
|
$order_type_object = get_post_type_object( $type ); |
126
|
|
|
add_meta_box( 'woocommerce-order-data', sprintf( __( '%s Data', 'woocommerce' ), $order_type_object->labels->singular_name ), 'WC_Meta_Box_Order_Data::output', $type, 'normal', 'high' ); |
127
|
|
|
add_meta_box( 'woocommerce-order-items', sprintf( __( '%s Items', 'woocommerce' ), $order_type_object->labels->singular_name ), 'WC_Meta_Box_Order_Items::output', $type, 'normal', 'high' ); |
128
|
|
|
add_meta_box( 'woocommerce-order-notes', sprintf( __( '%s Notes', 'woocommerce' ), $order_type_object->labels->singular_name ), 'WC_Meta_Box_Order_Notes::output', $type, 'side', 'default' ); |
129
|
|
|
add_meta_box( 'woocommerce-order-downloads', __( 'Downloadable Product Permissions', 'woocommerce' ) . wc_help_tip( __( 'Note: Permissions for order items will automatically be granted when the order status changes to processing/completed.', 'woocommerce' ) ), 'WC_Meta_Box_Order_Downloads::output', $type, 'normal', 'default' ); |
130
|
|
|
add_meta_box( 'woocommerce-order-actions', sprintf( __( '%s Actions', 'woocommerce' ), $order_type_object->labels->singular_name ), 'WC_Meta_Box_Order_Actions::output', $type, 'side', 'high' ); |
131
|
|
|
remove_meta_box( 'submitdiv', $type, 'side' ); |
132
|
|
|
} |
133
|
|
|
|
134
|
|
|
// Coupons |
135
|
|
|
add_meta_box( 'woocommerce-coupon-data', __( 'Coupon Data', 'woocommerce' ), 'WC_Meta_Box_Coupon_Data::output', 'shop_coupon', 'normal', 'high' ); |
136
|
|
|
} |
137
|
|
|
|
138
|
|
|
/** |
139
|
|
|
* Remove bloat. |
140
|
|
|
*/ |
141
|
|
|
public function remove_meta_boxes() { |
142
|
|
|
remove_meta_box( 'postexcerpt', 'product', 'normal' ); |
143
|
|
|
remove_meta_box( 'product_shipping_classdiv', 'product', 'side' ); |
144
|
|
|
remove_meta_box( 'pageparentdiv', 'product', 'side' ); |
145
|
|
|
remove_meta_box( 'commentstatusdiv', 'product', 'normal' ); |
146
|
|
|
remove_meta_box( 'commentstatusdiv', 'product', 'side' ); |
147
|
|
|
remove_meta_box( 'woothemes-settings', 'shop_coupon', 'normal' ); |
148
|
|
|
remove_meta_box( 'commentstatusdiv', 'shop_coupon', 'normal' ); |
149
|
|
|
remove_meta_box( 'slugdiv', 'shop_coupon', 'normal' ); |
150
|
|
|
|
151
|
|
|
foreach ( wc_get_order_types( 'order-meta-boxes' ) as $type ) { |
152
|
|
|
remove_meta_box( 'commentsdiv', $type, 'normal' ); |
153
|
|
|
remove_meta_box( 'woothemes-settings', $type, 'normal' ); |
154
|
|
|
remove_meta_box( 'commentstatusdiv', $type, 'normal' ); |
155
|
|
|
remove_meta_box( 'slugdiv', $type, 'normal' ); |
156
|
|
|
} |
157
|
|
|
} |
158
|
|
|
|
159
|
|
|
/** |
160
|
|
|
* Rename core meta boxes. |
161
|
|
|
*/ |
162
|
|
|
public function rename_meta_boxes() { |
163
|
|
|
global $post; |
164
|
|
|
|
165
|
|
|
// Comments/Reviews |
166
|
|
|
if ( isset( $post ) && ( 'publish' == $post->post_status || 'private' == $post->post_status ) ) { |
167
|
|
|
remove_meta_box( 'commentsdiv', 'product', 'normal' ); |
168
|
|
|
|
169
|
|
|
add_meta_box( 'commentsdiv', __( 'Reviews', 'woocommerce' ), 'post_comment_meta_box', 'product', 'normal' ); |
170
|
|
|
} |
171
|
|
|
} |
172
|
|
|
|
173
|
|
|
/** |
174
|
|
|
* Check if we're saving, the trigger an action based on the post type. |
175
|
|
|
* |
176
|
|
|
* @param int $post_id |
177
|
|
|
* @param object $post |
178
|
|
|
*/ |
179
|
|
|
public function save_meta_boxes( $post_id, $post ) { |
180
|
|
|
// $post_id and $post are required |
181
|
|
|
if ( empty( $post_id ) || empty( $post ) || self::$saved_meta_boxes ) { |
182
|
|
|
return; |
183
|
|
|
} |
184
|
|
|
|
185
|
|
|
// Dont' save meta boxes for revisions or autosaves |
186
|
|
|
if ( defined( 'DOING_AUTOSAVE' ) || is_int( wp_is_post_revision( $post ) ) || is_int( wp_is_post_autosave( $post ) ) ) { |
187
|
|
|
return; |
188
|
|
|
} |
189
|
|
|
|
190
|
|
|
// Check the nonce |
191
|
|
|
if ( empty( $_POST['woocommerce_meta_nonce'] ) || ! wp_verify_nonce( $_POST['woocommerce_meta_nonce'], 'woocommerce_save_data' ) ) { |
192
|
|
|
return; |
193
|
|
|
} |
194
|
|
|
|
195
|
|
|
// Check the post being saved == the $post_id to prevent triggering this call for other save_post events |
196
|
|
|
if ( empty( $_POST['post_ID'] ) || $_POST['post_ID'] != $post_id ) { |
197
|
|
|
return; |
198
|
|
|
} |
199
|
|
|
|
200
|
|
|
// Check user has permission to edit |
201
|
|
|
if ( ! current_user_can( 'edit_post', $post_id ) ) { |
202
|
|
|
return; |
203
|
|
|
} |
204
|
|
|
|
205
|
|
|
// We need this save event to run once to avoid potential endless loops. This would have been perfect: |
206
|
|
|
// remove_action( current_filter(), __METHOD__ ); |
|
|
|
|
207
|
|
|
// But cannot be used due to https://github.com/woothemes/woocommerce/issues/6485 |
208
|
|
|
// When that is patched in core we can use the above. For now: |
209
|
|
|
self::$saved_meta_boxes = true; |
210
|
|
|
|
211
|
|
|
// Check the post type |
212
|
|
|
if ( in_array( $post->post_type, wc_get_order_types( 'order-meta-boxes' ) ) ) { |
213
|
|
|
do_action( 'woocommerce_process_shop_order_meta', $post_id, $post ); |
214
|
|
|
} elseif ( in_array( $post->post_type, array( 'product', 'shop_coupon' ) ) ) { |
215
|
|
|
do_action( 'woocommerce_process_' . $post->post_type . '_meta', $post_id, $post ); |
216
|
|
|
} |
217
|
|
|
} |
218
|
|
|
|
219
|
|
|
} |
220
|
|
|
|
221
|
|
|
new WC_Admin_Meta_Boxes(); |
222
|
|
|
|
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.