PageRenderTime 46ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/admin/post-types/writepanels/writepanels-init.php

https://github.com/CammoKing/woocommerce
PHP | 452 lines | 218 code | 96 blank | 138 comment | 48 complexity | ccb1e975f19f22d7bb07b10a94544b4e MD5 | raw file
Possible License(s): GPL-3.0
  1. <?php
  2. /**
  3. * WooCommerce Write Panels
  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/WritePanels
  10. * @version 1.7.0
  11. */
  12. if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
  13. /** Product data writepanel */
  14. include_once('writepanel-product_data.php');
  15. /** Product images writepanel */
  16. include_once('writepanel-product_images.php');
  17. /** Coupon data writepanel */
  18. include_once('writepanel-coupon_data.php');
  19. /** Order data writepanel */
  20. include_once('writepanel-order_data.php');
  21. /** Order notes writepanel */
  22. include_once('writepanel-order_notes.php');
  23. /** Order downloads writepanel */
  24. include_once('writepanel-order_downloads.php');
  25. /**
  26. * Init the meta boxes.
  27. *
  28. * Inits the write panels for both products and orders. Also removes unused default write panels.
  29. *
  30. * @access public
  31. * @return void
  32. */
  33. function woocommerce_meta_boxes() {
  34. global $post;
  35. // Products
  36. add_meta_box( 'woocommerce-product-data', __( 'Product Data', 'woocommerce' ), 'woocommerce_product_data_box', 'product', 'normal', 'high' );
  37. add_meta_box( 'woocommerce-product-images', __( 'Product Images', 'woocommerce' ), 'woocommerce_product_images_box', 'product', 'side' );
  38. remove_meta_box( 'product_shipping_classdiv', 'product', 'side' );
  39. remove_meta_box( 'pageparentdiv', 'product', 'side' );
  40. remove_meta_box( 'postimagediv', 'product', 'side' );
  41. // Excerpt
  42. if ( function_exists('wp_editor') ) {
  43. remove_meta_box( 'postexcerpt', 'product', 'normal' );
  44. add_meta_box( 'postexcerpt', __( 'Product Short Description', 'woocommerce' ), 'woocommerce_product_short_description_meta_box', 'product', 'normal' );
  45. }
  46. // Comments/Reviews
  47. remove_meta_box( 'commentstatusdiv', 'product', 'normal' );
  48. remove_meta_box( 'commentstatusdiv', 'product', 'side' );
  49. if ( ('publish' == $post->post_status || 'private' == $post->post_status) ) {
  50. remove_meta_box( 'commentsdiv', 'product', 'normal' );
  51. add_meta_box( 'commentsdiv', __( 'Reviews', 'woocommerce' ), 'post_comment_meta_box', 'product', 'normal' );
  52. }
  53. // Orders
  54. add_meta_box( 'woocommerce-order-data', __( 'Order Data', 'woocommerce' ), 'woocommerce_order_data_meta_box', 'shop_order', 'normal', 'high' );
  55. add_meta_box( 'woocommerce-order-items', __( 'Order Items', 'woocommerce' ) . ' <span class="tips" data-tip="' . __( 'Note: if you edit quantities or remove items from the order you will need to manually update stock levels.', 'woocommerce' ) . '">[?]</span>', 'woocommerce_order_items_meta_box', 'shop_order', 'normal', 'high');
  56. add_meta_box( 'woocommerce-order-totals', __( 'Order Totals', 'woocommerce' ), 'woocommerce_order_totals_meta_box', 'shop_order', 'side', 'default');
  57. add_meta_box( 'woocommerce-order-notes', __( 'Order Notes', 'woocommerce' ), 'woocommerce_order_notes_meta_box', 'shop_order', 'side', 'default');
  58. 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>', 'woocommerce_order_downloads_meta_box', 'shop_order', 'normal', 'default');
  59. add_meta_box( 'woocommerce-order-actions', __( 'Order Actions', 'woocommerce' ), 'woocommerce_order_actions_meta_box', 'shop_order', 'side', 'high');
  60. remove_meta_box( 'commentsdiv', 'shop_order' , 'normal' );
  61. remove_meta_box( 'woothemes-settings', 'shop_order' , 'normal' );
  62. remove_meta_box( 'commentstatusdiv', 'shop_order' , 'normal' );
  63. remove_meta_box( 'slugdiv', 'shop_order' , 'normal' );
  64. // Coupons
  65. add_meta_box( 'woocommerce-coupon-data', __( 'Coupon Data', 'woocommerce' ), 'woocommerce_coupon_data_meta_box', 'shop_coupon', 'normal', 'high');
  66. remove_meta_box( 'woothemes-settings', 'shop_coupon' , 'normal' );
  67. remove_meta_box( 'commentstatusdiv', 'shop_coupon' , 'normal' );
  68. remove_meta_box( 'slugdiv', 'shop_coupon' , 'normal' );
  69. }
  70. add_action( 'add_meta_boxes', 'woocommerce_meta_boxes' );
  71. /**
  72. * Change title boxes in admin.
  73. *
  74. * @access public
  75. * @param mixed $text
  76. * @param mixed $post
  77. * @return string
  78. */
  79. function woocommerce_enter_title_here( $text, $post ) {
  80. if ( $post->post_type == 'shop_coupon' ) return __( 'Coupon code', 'woocommerce' );
  81. if ( $post->post_type == 'product' ) return __( 'Product name', 'woocommerce' );
  82. return $text;
  83. }
  84. add_filter('enter_title_here', 'woocommerce_enter_title_here', 1, 2);
  85. /**
  86. * Save meta boxes
  87. *
  88. * Runs when a post is saved and does an action which the write panel save scripts can hook into.
  89. *
  90. * @access public
  91. * @param mixed $post_id
  92. * @param mixed $post
  93. * @return void
  94. */
  95. function woocommerce_meta_boxes_save( $post_id, $post ) {
  96. if ( empty( $post_id ) || empty( $post ) ) return;
  97. if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return;
  98. if ( is_int( wp_is_post_revision( $post ) ) ) return;
  99. if ( is_int( wp_is_post_autosave( $post ) ) ) return;
  100. if ( empty( $_POST['woocommerce_meta_nonce'] ) || ! wp_verify_nonce( $_POST['woocommerce_meta_nonce'], 'woocommerce_save_data' ) ) return;
  101. if ( !current_user_can( 'edit_post', $post_id )) return;
  102. if ( $post->post_type != 'product' && $post->post_type != 'shop_order' && $post->post_type != 'shop_coupon' ) return;
  103. do_action( 'woocommerce_process_' . $post->post_type . '_meta', $post_id, $post );
  104. woocommerce_meta_boxes_save_errors();
  105. }
  106. add_action( 'save_post', 'woocommerce_meta_boxes_save', 1, 2 );
  107. /**
  108. * Product Short Description.
  109. *
  110. * Replaces excerpt with a visual editor.
  111. *
  112. * @access public
  113. * @param mixed $post
  114. * @return void
  115. */
  116. function woocommerce_product_short_description_meta_box( $post ) {
  117. $settings = array(
  118. 'quicktags' => array( 'buttons' => 'em,strong,link' ),
  119. 'textarea_name' => 'excerpt',
  120. 'quicktags' => true,
  121. 'tinymce' => true,
  122. 'editor_css' => '<style>#wp-excerpt-editor-container .wp-editor-area{height:175px; width:100%;}</style>'
  123. );
  124. wp_editor( htmlspecialchars_decode( $post->post_excerpt ), 'excerpt', $settings );
  125. }
  126. /**
  127. * Change the comment box to be a review box.
  128. *
  129. * @access public
  130. * @param mixed $post
  131. * @return void
  132. */
  133. function woocommerce_product_review_status_meta_box( $post ) {
  134. ?>
  135. <input name="advanced_view" type="hidden" value="1" />
  136. <p class="meta-options">
  137. <label for="comment_status" class="selectit"><input name="comment_status" type="checkbox" id="comment_status" value="open" <?php checked($post->comment_status, 'open'); ?> /> <?php _e( 'Allow reviews.', 'woocommerce' ) ?></label><br />
  138. <label for="ping_status" class="selectit"><input name="ping_status" type="checkbox" id="ping_status" value="open" <?php checked($post->ping_status, 'open'); ?> /> <?php printf( __( 'Allow <a href="%s" target="_blank">trackbacks and pingbacks</a> on this page.' ), __( 'http://codex.wordpress.org/Introduction_to_Blogging#Managing_Comments' ) ); ?></label>
  139. <?php do_action('post_comment_status_meta_box-options', $post); ?>
  140. </p>
  141. <?php
  142. }
  143. /**
  144. * Forces certain product data based on the product's type, e.g. grouped products cannot have a parent.
  145. *
  146. * @access public
  147. * @param mixed $data
  148. * @return array
  149. */
  150. function woocommerce_product_data( $data ) {
  151. global $post;
  152. if ($data['post_type']=='product' && isset($_POST['product-type'])) {
  153. $product_type = stripslashes( $_POST['product-type'] );
  154. switch($product_type) :
  155. case "grouped" :
  156. case "variable" :
  157. $data['post_parent'] = 0;
  158. break;
  159. endswitch;
  160. }
  161. return $data;
  162. }
  163. add_filter('wp_insert_post_data', 'woocommerce_product_data');
  164. /**
  165. * Forces the order posts to have a title in a certain format (containing the date)
  166. *
  167. * @access public
  168. * @param mixed $data
  169. * @return array
  170. */
  171. function woocommerce_order_data( $data ) {
  172. global $post;
  173. if ($data['post_type']=='shop_order' && isset($data['post_date'])) {
  174. $order_title = 'Order';
  175. if ($data['post_date']) $order_title.= ' &ndash; ' . date_i18n( 'F j, Y @ h:i A', strtotime( $data['post_date'] ) );
  176. $data['post_title'] = $order_title;
  177. }
  178. return $data;
  179. }
  180. add_filter('wp_insert_post_data', 'woocommerce_order_data');
  181. /**
  182. * Grant downloadable file access to any newly added files on any existing
  183. * orders for this product that have previously been granted downloadable file access
  184. *
  185. * @access public
  186. * @param int $product_id product identifier
  187. * @param int $variation_id optional product variation identifier
  188. * @param array $file_paths newly set file paths
  189. */
  190. function woocommerce_process_product_file_download_paths( $product_id, $variation_id, $file_paths ) {
  191. global $wpdb;
  192. if ( $variation_id )
  193. $product_id = $variation_id;
  194. // determine whether any new files have been added
  195. $existing_file_paths = apply_filters( 'woocommerce_file_download_paths', get_post_meta( $product_id, '_file_paths', true ), $product_id, null, null );
  196. if ( ! $existing_file_paths ) $existing_file_paths = array();
  197. $new_download_ids = array_diff( array_keys( $file_paths ), array_keys( $existing_file_paths ) );
  198. if ( $new_download_ids ) {
  199. // determine whether downloadable file access has been granted (either via the typical order completion, or via the admin ajax method)
  200. $existing_permissions = $wpdb->get_results( $wpdb->prepare( "SELECT * from {$wpdb->prefix}woocommerce_downloadable_product_permissions WHERE product_id = %d GROUP BY order_id", $product_id ) );
  201. foreach ( $existing_permissions as $existing_permission ) {
  202. $order = new WC_Order( $existing_permission->order_id );
  203. if ( $order->id ) {
  204. foreach ( $new_download_ids as $new_download_id ) {
  205. // grant permission if it doesn't already exist
  206. if ( ! $wpdb->get_var( $wpdb->prepare( "SELECT true FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions WHERE order_id = %d AND product_id = %d AND download_id = %s", $order->id, $product_id, $new_download_id ) ) ) {
  207. woocommerce_downloadable_file_permission( $new_download_id, $product_id, $order );
  208. }
  209. }
  210. }
  211. }
  212. }
  213. }
  214. add_action( 'woocommerce_process_product_file_download_paths', 'woocommerce_process_product_file_download_paths', 10, 3 );
  215. /**
  216. * Stores error messages in a variable so they can be displayed on the edit post screen after saving.
  217. *
  218. * @access public
  219. * @return void
  220. */
  221. function woocommerce_meta_boxes_save_errors() {
  222. global $woocommerce_errors;
  223. update_option( 'woocommerce_errors', $woocommerce_errors );
  224. }
  225. add_action( 'admin_footer', 'woocommerce_meta_boxes_save_errors' );
  226. /**
  227. * Show any stored error messages.
  228. *
  229. * @access public
  230. * @return void
  231. */
  232. function woocommerce_meta_boxes_show_errors() {
  233. global $woocommerce_errors;
  234. $woocommerce_errors = maybe_unserialize( get_option( 'woocommerce_errors' ) );
  235. if ( ! empty( $woocommerce_errors ) ) {
  236. echo '<div id="woocommerce_errors" class="error fade">';
  237. foreach ( $woocommerce_errors as $error )
  238. echo '<p>' . esc_html( $error ) . '</p>';
  239. echo '</div>';
  240. // Clear
  241. update_option( 'woocommerce_errors', '' );
  242. $woocommerce_errors = array();
  243. }
  244. }
  245. add_action( 'admin_notices', 'woocommerce_meta_boxes_show_errors' );
  246. /**
  247. * Output a text input box.
  248. *
  249. * @access public
  250. * @param array $field
  251. * @return void
  252. */
  253. function woocommerce_wp_text_input( $field ) {
  254. global $thepostid, $post, $woocommerce;
  255. $thepostid = empty( $thepostid ) ? $post->ID : $thepostid;
  256. $field['placeholder'] = isset( $field['placeholder'] ) ? $field['placeholder'] : '';
  257. $field['class'] = isset( $field['class'] ) ? $field['class'] : 'short';
  258. $field['value'] = isset( $field['value'] ) ? $field['value'] : get_post_meta( $thepostid, $field['id'], true );
  259. $field['name'] = isset( $field['name'] ) ? $field['name'] : $field['id'];
  260. $field['type'] = isset( $field['type'] ) ? $field['type'] : 'text';
  261. // Custom attribute handling
  262. $custom_attributes = array();
  263. if ( ! empty( $field['custom_attributes'] ) && is_array( $field['custom_attributes'] ) )
  264. foreach ( $field['custom_attributes'] as $attribute => $value )
  265. $custom_attributes[] = esc_attr( $attribute ) . '="' . esc_attr( $value ) . '"';
  266. echo '<p class="form-field ' . esc_attr( $field['id'] ) . '_field"><label for="' . esc_attr( $field['id'] ) . '">' . wp_kses_post( $field['label'] ) . '</label><input type="' . esc_attr( $field['type'] ) . '" class="' . esc_attr( $field['class'] ) . '" name="' . esc_attr( $field['name'] ) . '" id="' . esc_attr( $field['id'] ) . '" value="' . esc_attr( $field['value'] ) . '" placeholder="' . esc_attr( $field['placeholder'] ) . '" ' . implode( ' ', $custom_attributes ) . ' /> ';
  267. if ( ! empty( $field['description'] ) ) {
  268. if ( isset( $field['desc_tip'] ) ) {
  269. echo '<img class="help_tip" data-tip="' . esc_attr( $field['description'] ) . '" src="' . $woocommerce->plugin_url() . '/assets/images/help.png" />';
  270. } else {
  271. echo '<span class="description">' . wp_kses_post( $field['description'] ) . '</span>';
  272. }
  273. }
  274. echo '</p>';
  275. }
  276. /**
  277. * Output a hidden input box.
  278. *
  279. * @access public
  280. * @param array $field
  281. * @return void
  282. */
  283. function woocommerce_wp_hidden_input( $field ) {
  284. global $thepostid, $post;
  285. $thepostid = empty( $thepostid ) ? $post->ID : $thepostid;
  286. $field['value'] = isset( $field['value'] ) ? $field['value'] : get_post_meta( $thepostid, $field['id'], true );
  287. $field['class'] = isset( $field['class'] ) ? $field['class'] : '';
  288. echo '<input type="hidden" class="' . esc_attr( $field['class'] ) . '" name="' . esc_attr( $field['id'] ) . '" id="' . esc_attr( $field['id'] ) . '" value="' . esc_attr( $field['value'] ) . '" /> ';
  289. }
  290. /**
  291. * Output a textarea input box.
  292. *
  293. * @access public
  294. * @param array $field
  295. * @return void
  296. */
  297. function woocommerce_wp_textarea_input( $field ) {
  298. global $thepostid, $post, $woocommerce;
  299. $thepostid = empty( $thepostid ) ? $post->ID : $thepostid;
  300. $field['placeholder'] = isset( $field['placeholder'] ) ? $field['placeholder'] : '';
  301. $field['class'] = isset( $field['class'] ) ? $field['class'] : 'short';
  302. $field['value'] = isset( $field['value'] ) ? $field['value'] : get_post_meta( $thepostid, $field['id'], true );
  303. echo '<p class="form-field ' . esc_attr( $field['id'] ) . '_field"><label for="' . esc_attr( $field['id'] ) . '">' . wp_kses_post( $field['label'] ) . '</label><textarea class="' . esc_attr( $field['class'] ) . '" name="' . esc_attr( $field['id'] ) . '" id="' . esc_attr( $field['id'] ) . '" placeholder="' . esc_attr( $field['placeholder'] ) . '" rows="2" cols="20">' . esc_textarea( $field['value'] ) . '</textarea> ';
  304. if ( ! empty( $field['description'] ) ) {
  305. if ( isset( $field['desc_tip'] ) ) {
  306. echo '<img class="help_tip" data-tip="' . esc_attr( $field['description'] ) . '" src="' . $woocommerce->plugin_url() . '/assets/images/help.png" />';
  307. } else {
  308. echo '<span class="description">' . wp_kses_post( $field['description'] ) . '</span>';
  309. }
  310. }
  311. echo '</p>';
  312. }
  313. /**
  314. * Output a checkbox input box.
  315. *
  316. * @access public
  317. * @param array $field
  318. * @return void
  319. */
  320. function woocommerce_wp_checkbox( $field ) {
  321. global $thepostid, $post;
  322. $thepostid = empty( $thepostid ) ? $post->ID : $thepostid;
  323. $field['class'] = isset( $field['class'] ) ? $field['class'] : 'checkbox';
  324. $field['wrapper_class'] = isset( $field['wrapper_class'] ) ? $field['wrapper_class'] : '';
  325. $field['value'] = isset( $field['value'] ) ? $field['value'] : get_post_meta( $thepostid, $field['id'], true );
  326. $field['cbvalue'] = isset( $field['cbvalue'] ) ? $field['cbvalue'] : 'yes';
  327. echo '<p class="form-field ' . esc_attr( $field['id'] ) . '_field ' . esc_attr( $field['wrapper_class'] ) . '"><label for="' . esc_attr( $field['id'] ) . '">' . wp_kses_post( $field['label'] ) . '</label><input type="checkbox" class="' . esc_attr( $field['class'] ) . '" name="' . esc_attr( $field['id'] ) . '" id="' . esc_attr( $field['id'] ) . '" value="' . esc_attr( $field['cbvalue'] ) . '" ' . checked( $field['value'], $field['cbvalue'], false ) . ' /> ';
  328. if ( ! empty( $field['description'] ) ) echo '<span class="description">' . wp_kses_post( $field['description'] ) . '</span>';
  329. echo '</p>';
  330. }
  331. /**
  332. * Output a select input box.
  333. *
  334. * @access public
  335. * @param array $field
  336. * @return void
  337. */
  338. function woocommerce_wp_select( $field ) {
  339. global $thepostid, $post, $woocommerce;
  340. $thepostid = empty( $thepostid ) ? $post->ID : $thepostid;
  341. $field['class'] = isset( $field['class'] ) ? $field['class'] : 'select short';
  342. $field['value'] = isset( $field['value'] ) ? $field['value'] : get_post_meta( $thepostid, $field['id'], true );
  343. echo '<p class="form-field ' . esc_attr( $field['id'] ) . '_field"><label for="' . esc_attr( $field['id'] ) . '">' . wp_kses_post( $field['label'] ) . '</label><select id="' . esc_attr( $field['id'] ) . '" name="' . esc_attr( $field['id'] ) . '" class="' . esc_attr( $field['class'] ) . '">';
  344. foreach ( $field['options'] as $key => $value ) {
  345. echo '<option value="' . esc_attr( $key ) . '" ' . selected( esc_attr( $field['value'] ), esc_attr( $key ), false ) . '>' . esc_html( $value ) . '</option>';
  346. }
  347. echo '</select> ';
  348. if ( ! empty( $field['description'] ) ) {
  349. if ( isset( $field['desc_tip'] ) ) {
  350. echo '<img class="help_tip" data-tip="' . esc_attr( $field['description'] ) . '" src="' . $woocommerce->plugin_url() . '/assets/images/help.png" />';
  351. } else {
  352. echo '<span class="description">' . wp_kses_post( $field['description'] ) . '</span>';
  353. }
  354. }
  355. echo '</p>';
  356. }