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' ) ) exit; // Exit if accessed directly
 14 
 15 /**
 16  * WC_Admin_Meta_Boxes
 17  */
 18 class WC_Admin_Meta_Boxes {
 19 
 20     private static $meta_box_errors = array();
 21 
 22     /**
 23      * Constructor
 24      */
 25     public function __construct() {
 26         add_action( 'add_meta_boxes', array( $this, 'remove_meta_boxes' ), 10 );
 27         add_action( 'add_meta_boxes', array( $this, 'rename_meta_boxes' ), 20 );
 28         add_action( 'add_meta_boxes', array( $this, 'add_meta_boxes' ), 30 );
 29         add_action( 'add_meta_boxes', array( 'WC_Gateway_Mijireh', 'add_page_slurp_meta' ) );
 30         add_action( 'save_post', array( $this, 'save_meta_boxes' ), 1, 2 );
 31 
 32         /**
 33          * Save Order Meta Boxes
 34          *
 35          * In order:
 36          *      Save the order items
 37          *      Save the order totals
 38          *      Save the order downloads
 39          *      Save order data - also updates status and sends out admin emails if needed. Last to show latest data.
 40          *      Save actions - sends out other emails. Last to show latest data.
 41          */
 42         add_action( 'woocommerce_process_shop_order_meta', 'WC_Meta_Box_Order_Items::save', 10, 2 );
 43         add_action( 'woocommerce_process_shop_order_meta', 'WC_Meta_Box_Order_Totals::save', 20, 2 );
 44         add_action( 'woocommerce_process_shop_order_meta', 'WC_Meta_Box_Order_Downloads::save', 30, 2 );
 45         add_action( 'woocommerce_process_shop_order_meta', 'WC_Meta_Box_Order_Data::save', 40, 2 );
 46         add_action( 'woocommerce_process_shop_order_meta', 'WC_Meta_Box_Order_Actions::save', 50, 2 );
 47 
 48         // Save Product Meta Boxes
 49         add_action( 'woocommerce_process_product_meta', 'WC_Meta_Box_Product_Data::save', 10, 2 );
 50         add_action( 'woocommerce_process_product_meta', 'WC_Meta_Box_Product_Images::save', 20, 2 );
 51 
 52         // Save Coupon Meta Boxes
 53         add_action( 'woocommerce_process_shop_coupon_meta', 'WC_Meta_Box_Coupon_Data::save', 10, 2 );
 54 
 55         // Save Rating Meta Boxes
 56         add_action( 'comment_edit_redirect',  'WC_Meta_Box_Order_Reviews::save', 1, 2 );
 57 
 58         // Error handling (for showing errors from meta boxes on next page load)
 59         add_action( 'admin_notices', array( $this, 'output_errors' ) );
 60         add_action( 'shutdown', array( $this, 'save_errors' ) );
 61     }
 62 
 63     /**
 64      * Add an error message
 65      * @param string $text
 66      */
 67     public static function add_error( $text ) {
 68         self::$meta_box_errors[] = $text;
 69     }
 70 
 71     /**
 72      * Save errors to an option
 73      */
 74     public function save_errors() {
 75         update_option( 'woocommerce_meta_box_errors', self::$meta_box_errors );
 76     }
 77 
 78     /**
 79      * Show any stored error messages.
 80      */
 81     public function output_errors() {
 82         $errors = maybe_unserialize( get_option( 'woocommerce_meta_box_errors' ) );
 83 
 84         if ( ! empty( $errors ) ) {
 85 
 86             echo '<div id="woocommerce_errors" class="error fade">';
 87             foreach ( $errors as $error ) {
 88                 echo '<p>' . esc_html( $error ) . '</p>';
 89             }
 90             echo '</div>';
 91 
 92             // Clear
 93             delete_option( 'woocommerce_meta_box_errors' );
 94         }
 95     }
 96 
 97     /**
 98      * Add WC Meta boxes
 99      */
100     public function add_meta_boxes() {
101         // Products
102         add_meta_box( 'postexcerpt', __( 'Product Short Description', 'woocommerce' ), 'WC_Meta_Box_Product_Short_Description::output', 'product', 'normal' );
103         add_meta_box( 'woocommerce-product-data', __( 'Product Data', 'woocommerce' ), 'WC_Meta_Box_Product_Data::output', 'product', 'normal', 'high' );
104         add_meta_box( 'woocommerce-product-images', __( 'Product Gallery', 'woocommerce' ), 'WC_Meta_Box_Product_Images::output', 'product', 'side' );
105 
106         // Orders
107         add_meta_box( 'woocommerce-order-data', __( 'Order Data', 'woocommerce' ), 'WC_Meta_Box_Order_Data::output', 'shop_order', 'normal', 'high' );
108         add_meta_box( 'woocommerce-order-items', __( 'Order Items', 'woocommerce' ), 'WC_Meta_Box_Order_Items::output', 'shop_order', 'normal', 'high' );
109         add_meta_box( 'woocommerce-order-totals', __( 'Order Totals', 'woocommerce' ), 'WC_Meta_Box_Order_Totals::output', 'shop_order', 'side', 'default' );
110         add_meta_box( 'woocommerce-order-notes', __( 'Order Notes', 'woocommerce' ), 'WC_Meta_Box_Order_Notes::output', 'shop_order', 'side', 'default' );
111         add_meta_box( 'woocommerce-order-downloads', __( 'Downloadable Product Permissions', 'woocommerce' ) . ' <span class="tips" data-tip="' . __( 'Note: Permissions for order items will automatically be granted when the order status changes to processing/completed.', 'woocommerce' ) . '">[?]</span>', 'WC_Meta_Box_Order_Downloads::output', 'shop_order', 'normal', 'default' );
112         add_meta_box( 'woocommerce-order-actions', __( 'Order Actions', 'woocommerce' ), 'WC_Meta_Box_Order_Actions::output', 'shop_order', 'side', 'high' );
113 
114         // Coupons
115         add_meta_box( 'woocommerce-coupon-data', __( 'Coupon Data', 'woocommerce' ), 'WC_Meta_Box_Coupon_Data::output', 'shop_coupon', 'normal', 'high' );
116 
117         // Reviews
118         if ( 'comment' == get_current_screen()->id && isset( $_GET['c'] ) ) {
119             if ( get_comment_meta( intval( $_GET['c'] ), 'rating', true ) ) {
120                 add_meta_box( 'woocommerce-rating', __( 'Rating', 'woocommerce' ), 'WC_Meta_Box_Order_Reviews::output', 'comment', 'normal', 'high' );
121             }
122         }
123     }
124 
125     /**
126      * Remove bloat
127      */
128     public function remove_meta_boxes() {
129         remove_meta_box( 'postexcerpt', 'product', 'normal' );
130         remove_meta_box( 'product_shipping_classdiv', 'product', 'side' );
131         remove_meta_box( 'pageparentdiv', 'product', 'side' );
132         remove_meta_box( 'commentstatusdiv', 'product', 'normal' );
133         remove_meta_box( 'commentstatusdiv', 'product', 'side' );
134         remove_meta_box( 'woothemes-settings', 'shop_coupon' , 'normal' );
135         remove_meta_box( 'commentstatusdiv', 'shop_coupon' , 'normal' );
136         remove_meta_box( 'slugdiv', 'shop_coupon' , 'normal' );
137         remove_meta_box( 'commentsdiv', 'shop_order' , 'normal' );
138         remove_meta_box( 'woothemes-settings', 'shop_order' , 'normal' );
139         remove_meta_box( 'commentstatusdiv', 'shop_order' , 'normal' );
140         remove_meta_box( 'slugdiv', 'shop_order' , 'normal' );
141     }
142 
143     /**
144      * Rename core meta boxes
145      */
146     public function rename_meta_boxes() {
147         global $post;
148 
149         // Comments/Reviews
150         if ( isset( $post ) && ( 'publish' == $post->post_status || 'private' == $post->post_status ) ) {
151             remove_meta_box( 'commentsdiv', 'product', 'normal' );
152 
153             add_meta_box( 'commentsdiv', __( 'Reviews', 'woocommerce' ), 'post_comment_meta_box', 'product', 'normal' );
154         }
155     }
156 
157     /**
158      * Check if we're saving, the trigger an action based on the post type
159      *
160      * @param  int $post_id
161      * @param  object $post
162      */
163     public function save_meta_boxes( $post_id, $post ) {
164         // $post_id and $post are required
165         if ( empty( $post_id ) || empty( $post ) ) {
166             return;
167         }
168 
169         // Dont' save meta boxes for revisions or autosaves
170         if ( defined( 'DOING_AUTOSAVE' ) || is_int( wp_is_post_revision( $post ) ) || is_int( wp_is_post_autosave( $post ) ) ) {
171             return;
172         }
173         
174         // Check the nonce
175         if ( empty( $_POST['woocommerce_meta_nonce'] ) || ! wp_verify_nonce( $_POST['woocommerce_meta_nonce'], 'woocommerce_save_data' ) ) {
176             return;
177         } 
178 
179         // Check the post being saved == the $post_id to prevent triggering this call for other save_post events
180         if ( empty( $_POST['post_ID'] ) || $_POST['post_ID'] != $post_id ) {
181             return;
182         }
183 
184         // Check user has permission to edit
185         if ( ! current_user_can( 'edit_post', $post_id ) ) {
186             return;
187         }
188 
189         // Check the post type
190         if ( ! in_array( $post->post_type, array( 'product', 'shop_order', 'shop_coupon' ) ) ) {
191             return;
192         }
193 
194         do_action( 'woocommerce_process_' . $post->post_type . '_meta', $post_id, $post );
195     }
196 
197 }
198 
199 new WC_Admin_Meta_Boxes();
200 
WooCommerce API documentation generated by ApiGen 2.8.0