PageRenderTime 46ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/admin/write-panels/product-types/variable.php

https://github.com/ThemesWpFr/jigoshop
PHP | 629 lines | 422 code | 89 blank | 118 comment | 48 complexity | 9d76018ad07fbc624b128bddcc3101b9 MD5 | raw file
Possible License(s): GPL-3.0
  1. <?php
  2. /**
  3. * Variable Product Type
  4. *
  5. * Functions specific to variable products (for the write panels)
  6. *
  7. * DISCLAIMER
  8. *
  9. * Do not edit or add directly to this file if you wish to upgrade Jigoshop to newer
  10. * versions in the future. If you wish to customise Jigoshop core for your needs,
  11. * please use our GitHub repository to publish essential changes for consideration.
  12. *
  13. * @package Jigoshop
  14. * @category Admin
  15. * @author Jigowatt
  16. * @copyright Copyright Š 2011-2012 Jigowatt Ltd.
  17. * @license http://jigoshop.com/license/commercial-edition
  18. */
  19. // Temporary fix for selectbox triggering the click event.
  20. // For some reason enqueing the script inside a class causes the event unbind()
  21. // to not work. Would prefer this to be part of the class but perhaps its better to enqueue
  22. // everything all at once.
  23. add_action( 'admin_enqueue_scripts', 'jigoshop_product_meta_variable_script' );
  24. function jigoshop_product_meta_variable_script( $hook ) {
  25. global $post;
  26. // Don't enqueue script if not on product edit screen
  27. if ( $hook != 'post.php' || $post->post_type != 'product' )
  28. return false;
  29. wp_enqueue_script('jigoshop-variable-js', jigoshop::assets_url() . '/assets/js/variable.js' , array('jquery'),1,true);
  30. }
  31. class jigoshop_product_meta_variable extends jigoshop_product_meta
  32. {
  33. public function __construct() {
  34. add_action( 'jigoshop_product_write_panel_tabs', array($this, 'register_tab') );
  35. add_action( 'jigoshop_process_product_meta_variable', array($this, 'save'), 1 );
  36. add_action( 'jigoshop_product_write_panels', array($this, 'display') );
  37. add_action( 'admin_enqueue_scripts', array($this, 'admin_enqueue_scripts') );
  38. add_action( 'wp_ajax_jigoshop_remove_variation', array($this, 'remove') );
  39. }
  40. /**
  41. * Registers tab for use in the product meta box
  42. *
  43. * @return void
  44. */
  45. public function register_tab() {
  46. echo '<li class="variable_tab">
  47. <a href="#variable_product_options">'.__('Variations','jigoshop').'</a>
  48. </li>';
  49. }
  50. /**
  51. * Registers scripts for use in the admin
  52. * Also localizes variables for use in the javascript, essential for variation addition
  53. *
  54. * @return void
  55. */
  56. public function admin_enqueue_scripts( $hook ) {
  57. global $post;
  58. // Don't enqueue script if not on product edit screen
  59. if ( $hook != 'post.php' || $post->post_type != 'product' )
  60. return false;
  61. // wp_enqueue_script('jigoshop-variable-js', jigoshop::assets_url() . '/assets/js/variable.js', array('postbox', 'jquery'), true);
  62. wp_localize_script( 'jigoshop-variable-js', 'varmeta', array(
  63. 'assets_url' => jigoshop::assets_url(),
  64. 'ajax_url' => admin_url('admin-ajax.php'),
  65. 'i18n' => array(
  66. 'variations_required' => __('You need to add some variations first', 'jigoshop'),
  67. 'remove_all' => __('Are you sure you want to delete all variations', 'jigoshop'),
  68. 'set_regular_price' => __('Enter a regular price', 'jigoshop'),
  69. 'set_sale_price' => __('Enter a sale price', 'jigoshop'),
  70. 'set_stock' => __('Enter a stock value', 'jigoshop'),
  71. 'set_weight' => __('Enter a weight value', 'jigoshop'),
  72. 'set_width' => __('Enter a width value', 'jigoshop'),
  73. 'set_length' => __('Enter a length value', 'jigoshop'),
  74. 'set_height' => __('Enter a height value', 'jigoshop'),
  75. ),
  76. 'actions' => array(
  77. 'remove' => array(
  78. 'action' => 'jigoshop_remove_variation',
  79. 'nonce' => wp_create_nonce("delete-variation"),
  80. 'confirm' => __('Are you sure you want to remove this variation?', 'jigoshop'),
  81. ),
  82. 'create' => array(
  83. 'action' => 'jigoshop_create_variation',
  84. 'panel' => $this->generate_panel(maybe_unserialize( get_post_meta($post->ID, 'product_attributes', true) ))
  85. )
  86. )
  87. ));
  88. }
  89. /**
  90. * Echos a variable type option for the product type selector
  91. *
  92. * @return void
  93. */
  94. public function register( $type ) {
  95. echo '<option value="variable" ' . selected($type, 'variable', false) . '>' . __('Variable', 'jigoshop') . '</option>';
  96. }
  97. /**
  98. * Removes a product variation via XHR
  99. *
  100. * @return void
  101. */
  102. public function remove() {
  103. check_ajax_referer( 'delete-variation', 'security' );
  104. $ID = intval( $_POST['variation_id'] );
  105. wp_set_object_terms( $ID, null, 'product_type'); // Remove object terms
  106. wp_delete_post( $ID );
  107. exit;
  108. }
  109. /**
  110. * Process the product variable meta
  111. *
  112. * @param int Product ID
  113. * @return void
  114. */
  115. public function save( $parent_id ) {
  116. global $wpdb;
  117. // Do not run if there are no variations
  118. if ( ! isset($_POST['variations']) )
  119. return false;
  120. // Get the attributes to be used later
  121. $attributes = (array) maybe_unserialize( get_post_meta($parent_id, 'product_attributes', true) );
  122. foreach ( $_POST['variations'] as $ID => $meta ) {
  123. /**
  124. * Generate a post title of the current variation.
  125. * Parent Title - [attribute: variation]
  126. */
  127. $taxes = array();
  128. foreach ( $meta as $k => $v ) :
  129. if ( strstr ( $k, 'tax_' ) ) {
  130. $tax = substr( $k, 4 );
  131. $taxes[] = sprintf('[%s: %s]', $tax, !empty($v) ? $v : 'Any ' . $tax );
  132. }
  133. endforeach;
  134. $post_title = !empty($_POST['post_title']) ? $_POST['post_title'] : the_title('','',false);
  135. $title = sprintf('%s - %s', $post_title, implode( $taxes, ' ' ) );
  136. /**
  137. * Prevent duplicate variations
  138. */
  139. // Update post data or Add post if new
  140. if ( strpos( $ID, '_new' ) ) {
  141. // check for an existing variation with matching attributes to prevent duplication
  142. $current_meta = $meta;
  143. foreach ( $current_meta as $current_id => $current_value ) {
  144. // discard everything but the taxonomies
  145. if ( strpos( $current_id, 'tax_' ) !== 0 ) {
  146. unset( $current_meta[$current_id] );
  147. }
  148. }
  149. // we now have just the taxonomies in use for this new variation in $current_meta, match them up to others
  150. $all_variations = $_POST['variations'];
  151. unset( $all_variations[$ID] ); // we don't need the current new variation
  152. $duplicate = false;
  153. foreach ( $all_variations as $this_id => $this_meta ) {
  154. $haystack_meta = $this_meta;
  155. foreach ( $haystack_meta as $haystack_id => $haystack_value ) {
  156. // discard everything but the taxonomies
  157. if ( strpos( $haystack_id, 'tax_' ) !== 0 ) {
  158. unset( $haystack_meta[$haystack_id] );
  159. }
  160. }
  161. // we now have the taxonomies only for this haystack variation
  162. $result = array_diff( $haystack_meta, $current_meta );
  163. if ( empty( $result ) ) $duplicate = true;
  164. }
  165. if ( ! $duplicate ) {
  166. $ID = wp_insert_post( array(
  167. 'post_title' => !empty($title) ? $title : "#{$parent_id}: Child Variation",
  168. 'post_status' => isset($meta['enabled']) ? 'publish' : 'draft',
  169. 'post_parent' => $parent_id,
  170. 'post_type' => 'product_variation'
  171. ));
  172. } else {
  173. // silent fail, should put up a message?
  174. }
  175. } else {
  176. $wpdb->update( $wpdb->posts, array(
  177. 'post_title' => !empty($title) ? $title : "#{$parent_id}: Child Variation",
  178. 'post_status' => isset($meta['enabled']) ? 'publish' : 'draft'
  179. ), array( 'ID' => $ID ) );
  180. }
  181. // Set the product type
  182. // NOTE: I think this will work, not sure -Rob
  183. wp_set_object_terms( $ID, sanitize_title($meta['product-type']), 'product_type');
  184. // Set variation meta data
  185. update_post_meta( $ID, 'sku', $meta['sku'] );
  186. update_post_meta( $ID, 'regular_price', $meta['regular_price'] );
  187. $sale_price = ! empty( $meta['sale_price'] )
  188. ? ( !strstr( $meta['sale_price'], '%' ) ? jigoshop_sanitize_num( $meta['sale_price'] ) : $meta['sale_price'] )
  189. : '';
  190. if ( strstr( $meta['sale_price'], '%' ) ) {
  191. update_post_meta( $ID, 'sale_price', $sale_price );
  192. } else if ( ! empty( $sale_price ) && $sale_price < jigoshop_sanitize_num( $meta['regular_price'] ) ) {
  193. update_post_meta( $ID, 'sale_price', $sale_price );
  194. } else {
  195. // silently fail if entered sale price > regular price (or nothing entered)
  196. update_post_meta( $ID, 'sale_price', '' );
  197. }
  198. update_post_meta( $ID, 'weight', $meta['weight'] );
  199. update_post_meta( $ID, 'length', $meta['length'] );
  200. update_post_meta( $ID, 'height', $meta['height'] );
  201. update_post_meta( $ID, 'width', $meta['width'] );
  202. update_post_meta( $ID, 'stock', $meta['stock'] );
  203. update_post_meta( $ID, '_thumbnail_id', $meta['_thumbnail_id'] );
  204. // Downloadable Only
  205. if( $meta['product-type'] == 'downloadable' ) {
  206. update_post_meta( $ID, 'file_path', $meta['file_path']);
  207. update_post_meta( $ID, 'download_limit', $meta['download_limit']);
  208. }
  209. // Refresh taxonomy attributes
  210. $current_meta = get_post_custom( $ID );
  211. // Remove the current data
  212. delete_post_meta( $ID, 'variation_data' );
  213. // Update taxonomies
  214. $variation_data = array();
  215. foreach ( $attributes as $attribute ) {
  216. // Skip if attribute is not for variation
  217. if ( ! $attribute['variation'] )
  218. continue;
  219. // Configure the data
  220. $key = 'tax_' . sanitize_title($attribute['name']);
  221. $variation_data[$key] = $meta[$key];
  222. }
  223. update_post_meta( $ID, 'variation_data', $variation_data );
  224. do_action( 'jigoshop_variable_product_table_data_save' , $ID, $meta);
  225. }
  226. }
  227. public function display() {
  228. global $post;
  229. // Get the attributes
  230. $attributes = (array) maybe_unserialize( get_post_meta($post->ID, 'product_attributes', true) );
  231. // Get all variations of the product
  232. $variations = get_posts(array(
  233. 'post_type' => 'product_variation',
  234. 'post_status' => array('draft', 'publish'),
  235. 'numberposts' => -1,
  236. 'orderby' => 'id',
  237. 'order' => 'desc',
  238. 'post_parent' => $post->ID
  239. ));
  240. ?>
  241. <div id='variable_product_options' class='panel'>
  242. <?php if($this->has_variable_attributes($attributes)): ?>
  243. <div class="toolbar">
  244. <select name="variation_actions">
  245. <option value="default"><?php _e('Bulk Actions', 'jigoshop') ?></option>
  246. <option value="remove_all"><?php _e('Remove All Variations', 'jigoshop') ?></option>
  247. <optgroup label="<?php _e('Set All', 'jigoshop') ?>:">
  248. <option value="set_all_regular_prices"><?php _e('Regular Prices', 'jigoshop') ?></option>
  249. <option value="set_all_sale_prices"><?php _e('Sale Prices', 'jigoshop') ?></option>
  250. <option value="set_all_stock"><?php _e('Stock', 'jigoshop') ?></option>
  251. <option value="set_all_weight"><?php _e('Weight', 'jigoshop') ?></option>
  252. <option value="set_all_width"><?php _e('Width', 'jigoshop') ?></option>
  253. <option value="set_all_length"><?php _e('Length', 'jigoshop') ?></option>
  254. <option value="set_all_height"><?php _e('Height', 'jigoshop') ?></option>
  255. </optgroup>
  256. </select>
  257. <input id="do_actions" type="submit" class="button-secondary" value="<?php _e('Apply','jigoshop'); ?>">
  258. <button type='button' class='button button-seconday add_variation'><?php _e('Add Variation', 'jigoshop') ?></button>
  259. </div>
  260. <?php endif; ?>
  261. <div class='jigoshop_variations'>
  262. <!-- Disabling Demo variation help display for 1.3 per support personnel request -JAP- -->
  263. <!--?php if ( ! $variations ): ?-->
  264. <!--div class="demo variation ">
  265. <a href="http://forum.jigoshop.com/kb/creating-products/variable-products" target="_blank" class="overlay"><span><?php _e('Learn how to make a Variation', 'jigoshop'); ?></span></a>
  266. <div class="inside">
  267. <div class="jigoshop_variation postbox">
  268. <button type="button" class="remove_variation button">Remove</button>
  269. <div class="handlediv" title="Click to toggle"><br></div>
  270. <h3 class="handle">
  271. <select>
  272. <option value="Medium">Medium</option>
  273. </select>
  274. </h3>
  275. <div class="inside">
  276. <table cellspacing="0" cellpadding="0" class="jigoshop_variable_attributes">
  277. <tr>
  278. <td class="upload_image" rowspan="2">
  279. <a href="#" class="upload_image_button " rel="0_new">
  280. <img src="<?php echo jigoshop::assets_url().'/assets/images/placeholder.png' ?>" width="93px">
  281. <input type="hidden" class="upload_image_id" value="">
  282. </a>
  283. </td>
  284. <td>
  285. <label class="clearlabel">Type</label>
  286. <select class="product_type">
  287. <option value="simple">Simple</option>
  288. </select>
  289. </td>
  290. <td>
  291. <label>SKU
  292. <input type="text" value="SKU1" />
  293. </label>
  294. </td>
  295. <td>
  296. <label>Stock Qty
  297. <input type="text" value="12">
  298. </label>
  299. </td>
  300. <td>
  301. <label>Price
  302. <input type="text" value="19.99">
  303. </label>
  304. </td>
  305. <td>
  306. <label>Sale Price
  307. <input type="text" value="13.99">
  308. </label>
  309. </td>
  310. <td>
  311. <label>Enabled
  312. <input type="checkbox" class="checkbox" checked="checked">
  313. </label>
  314. </td>
  315. </tr>
  316. <tr class="simple options">
  317. <td>
  318. <label>Weight
  319. <input type="text" value="22.5">
  320. </label>
  321. </td>
  322. <td colspan="4" class="dimensions">
  323. <label>Dimensions <?php echo '('. Jigoshop_Base::get_options()->get_option('jigoshop_dimension_unit'). ')' ?></label>
  324. <input type="text" placeholder="Length" value="">
  325. <input type="text" placeholder="Width" value="">
  326. <input type="text" placeholder="Height" value="">
  327. </td>
  328. <td colspan="3">&nbsp;</td>
  329. </tr>
  330. </table>
  331. </div>
  332. </div>
  333. </div>
  334. </div-->
  335. <!--?php endif; ?-->
  336. <?php if ( $this->has_variable_attributes( $attributes ) ): ?>
  337. <?php
  338. if( $variations ) {
  339. foreach( $variations as $variation ) {
  340. echo $this->generate_panel($attributes, $variation);
  341. }
  342. }
  343. ?>
  344. <?php endif; ?>
  345. </div>
  346. </div>
  347. <?php
  348. }
  349. /**
  350. * Returns a specially formatted field name for variations
  351. *
  352. * @param string Field Name
  353. * @param object Variation Post Object
  354. * @return string
  355. */
  356. private function field_name( $name, $variation = null ) {
  357. return "variations[{$variation->ID}][{$name}]";
  358. }
  359. /**
  360. * Returns all the possible variable attributes in select form
  361. *
  362. * @param array Attributes array
  363. * @param object Variation Post Object
  364. * @return HTML
  365. */
  366. private function attribute_selector( $attributes, $variation = null ) {
  367. global $post;
  368. $html = null;
  369. if ( ! is_ajax() ) {
  370. $variation_data = get_post_meta( $variation->ID, 'variation_data' );
  371. }
  372. // Attribute Variation Selector
  373. foreach ( $attributes as $attr ) {
  374. // If not variable attribute then skip
  375. if ( ! $attr['variation'] )
  376. continue;
  377. // Get current value for variation (if set)
  378. if ( ! is_ajax() ) {
  379. $selected = $variation_data[0][ 'tax_' . sanitize_title($attr['name']) ];
  380. }
  381. // Open the select & set a default value
  382. $html .= '<select name="' . $this->field_name('tax_' . sanitize_title($attr['name']), $variation) . '" >
  383. <option value="">'.__('Any', 'jigoshop') . ' ' .jigoshop_product::attribute_label('pa_'.$attr['name']).'&hellip;</option>';
  384. // Get terms for attribute taxonomy or value if its a custom attribute
  385. if ( $attr['is_taxonomy'] ) {
  386. $options = wp_get_object_terms( $post->ID, 'pa_'.sanitize_title($attr['name']), array( 'orderby' => 'slug' ) );
  387. foreach( $options as $option ) {
  388. $html .= '<option value="'.esc_attr($option->slug).'" '.selected($selected, $option->slug, false).'>'.$option->name.'</option>';
  389. }
  390. }
  391. else {
  392. $options = explode(',', $attr['value']);
  393. foreach( $options as $option ) {
  394. $option = trim($option);
  395. $html .= '<option '.selected($selected, $option, false).' value="'.esc_attr($option).'">'.$option.'</option>';
  396. }
  397. }
  398. // Close the select
  399. $html .= '</select>';
  400. }
  401. return $html;
  402. }
  403. /**
  404. * Checks all the product attributes for variation defined attributes
  405. *
  406. * @param mixed Attributes
  407. * @return bool
  408. */
  409. private function has_variable_attributes( $attributes ) {
  410. if ( ! $attributes )
  411. return false;
  412. foreach ( $attributes as $attribute ) {
  413. if ( isset($attribute['variation']) && $attribute['variation'] )
  414. return true;
  415. }
  416. return false;
  417. }
  418. /**
  419. * Generates a variation panel
  420. *
  421. * @param array attributes
  422. * @param object variation
  423. * @return HTML
  424. */
  425. private function generate_panel($attributes, $variation = null) {
  426. if ( ! $this->has_variable_attributes($attributes) )
  427. return false;
  428. // Set the default image as the placeholder
  429. $image = jigoshop::assets_url().'/assets/images/placeholder.png';
  430. if ( ! $variation ) {
  431. // Create a blank variation object with a unique id
  432. $variation = new stdClass;
  433. $variation->ID = '__ID__';
  434. $variation->post_status = 'publish';
  435. }
  436. else {
  437. // Get the variation meta
  438. $meta = get_post_custom( $variation->ID );
  439. // If variation has a thumbnail display that
  440. if ( $image_id = $meta['_thumbnail_id'][0] )
  441. $image = wp_get_attachment_url( $image_id );
  442. }
  443. // Start buffering the output
  444. ob_start();
  445. ?>
  446. <div class="jigoshop_variation postbox closed" rel="<?php echo $variation->ID; ?>">
  447. <button type="button" class="remove_variation button"><?php _e('Remove', 'jigoshop'); ?></button>
  448. <div class="handlediv" title="Click to toggle"><br></div>
  449. <h3 class="handle"><?php echo $this->attribute_selector($attributes, $variation); ?></h3>
  450. <div class="inside">
  451. <table cellpadding="0" cellspacing="0" class="jigoshop_variable_attributes">
  452. <tbody>
  453. <?php do_action('jigoshop_variable_product_table_begin', $variation, $attributes)?>
  454. <tr>
  455. <td class="upload_image" rowspan="2">
  456. <a href="#" class="upload_image_button <?php if (isset($image_id)) echo 'remove'; ?>" rel="<?php echo $variation->ID; ?>">
  457. <img src="<?php echo $image ?>" width="93px" />
  458. <input type="hidden" name="<?php echo esc_attr( $this->field_name('_thumbnail_id', $variation) ); ?>" class="upload_image_id" value="<?php if ( isset($image_id)) echo esc_attr( $image_id ); ?>" />
  459. <!-- TODO: APPEND THIS IN JS <span class="overlay"></span> -->
  460. </a>
  461. </td>
  462. <td>
  463. <?php
  464. $terms = get_the_terms( $variation->ID, 'product_type' );
  465. $product_type = ($terms) ? current($terms)->slug : 'simple';
  466. ?>
  467. <label class="clearlabel"><?php _e('Type', 'jigoshop') ?></label>
  468. <select class="product_type" name="<?php echo esc_attr( $this->field_name('product-type', $variation) ); ?>">
  469. <option value="simple" <?php selected('simple', $product_type) ?>><?php _e('Simple', 'jigoshop') ?></option>
  470. <option value="downloadable" <?php selected('downloadable', $product_type) ?>><?php _e('Downloadable', 'jigoshop') ?></option>
  471. <option value="virtual" <?php selected('virtual', $product_type) ?>><?php _e('Virtual', 'jigoshop') ?></option>
  472. </select>
  473. </td>
  474. <td>
  475. <label><?php _e('SKU', 'jigoshop'); ?>
  476. <input type="text" name="<?php echo esc_attr( $this->field_name('sku', $variation) ); ?>" placeholder="<?php echo esc_attr( $variation->ID ); ?>" value="<?php echo esc_attr( isset($meta['sku'][0]) ? $meta['sku'][0] : null ); ?>" />
  477. </label>
  478. </td>
  479. <td>
  480. <label><?php _e('Stock Qty', 'jigoshop'); ?>
  481. <input type="text" name="<?php echo esc_attr( $this->field_name('stock', $variation) ); ?>" value="<?php echo esc_attr( isset($meta['stock'][0]) ? $meta['stock'][0] : null ); ?>" />
  482. </label>
  483. </td>
  484. <td>
  485. <label><?php _e('Price', 'jigoshop'); ?>
  486. <input type="text" name="<?php echo esc_attr( $this->field_name('regular_price', $variation) ); ?>" value="<?php echo esc_attr( isset($meta['regular_price'][0]) ? $meta['regular_price'][0] : null ); ?>" />
  487. </label>
  488. </td>
  489. <td>
  490. <label><?php _e('Sale Price', 'jigoshop'); ?>
  491. <input type="text" name="<?php echo esc_attr( $this->field_name('sale_price', $variation) ); ?>" value="<?php echo esc_attr( isset($meta['sale_price'][0]) ? $meta['sale_price'][0] : null ); ?>" />
  492. </label>
  493. </td>
  494. <td>
  495. <label><?php _e('Enabled', 'jigoshop'); ?>
  496. <input type="checkbox" class="checkbox" name="<?php echo esc_attr( $this->field_name('enabled', $variation) ); ?>" <?php checked($variation->post_status, 'publish'); ?> />
  497. </label>
  498. </td>
  499. </tr>
  500. <tr class="simple options" <?php echo ( ('simple' == $product_type) || ('variable' == $product_type)) ? 'style="display: table-row;"' : 'style="display: none;"';?>>
  501. <td>
  502. <label><?php _e('Weight', 'jigoshop') ?>
  503. <input type="text" name="<?php echo esc_attr( $this->field_name('weight', $variation) ); ?>" value="<?php echo esc_attr( isset($meta['weight'][0]) ? $meta['weight'][0] : null ); ?>" />
  504. </label>
  505. </td>
  506. <td colspan="4" class="dimensions">
  507. <label><?php _e('Dimensions', 'jigoshop') ?> <?php echo '('. Jigoshop_Base::get_options()->get_option('jigoshop_dimension_unit'). ')' ?></label>
  508. <input type="text" name="<?php echo esc_attr( $this->field_name('length', $variation) ); ?>" placeholder="<?php _e('Length', 'jigoshop') ?>" value="<?php echo esc_attr( isset($meta['length'][0]) ? $meta['length'][0] : null ); ?>" />
  509. <input type="text" name="<?php echo esc_attr( $this->field_name('width', $variation) ); ?>" placeholder="<?php _e('Width', 'jigoshop') ?>" value="<?php echo esc_attr( isset($meta['width'][0]) ? $meta['width'][0] : null ); ?>" />
  510. <input type="text" name="<?php echo esc_attr( $this->field_name('height', $variation) ); ?>" placeholder="<?php _e('Height', 'jigoshop') ?>" value="<?php echo esc_attr( isset($meta['height'][0]) ? $meta['height'][0] : null ); ?>" />
  511. <td colspan="3"></td>
  512. </td>
  513. </tr>
  514. <tr class="downloadable options" <?php echo ('downloadable' == $product_type) ? 'style="display: table-row;"' : 'style="display: none;"';?>>
  515. <td colspan="4" class="download_file">
  516. <label class="clearlabel"><?php _e('File Location', 'jigoshop') ?></label>
  517. <input type="text" name="<?php echo esc_attr( $this->field_name('file_path', $variation) ); ?>" value="<?php echo esc_attr( isset($meta['file_path'][0]) ? $meta['file_path'][0] : null ); ?>" />
  518. <input type="submit" class="upload_file_button button-secondary" value="Upload">
  519. </td>
  520. <td colspan="2">
  521. <label><?php _e('Re-downloads Limit', 'jigoshop') ?>
  522. <input type="text" name="<?php echo esc_attr( $this->field_name('download_limit', $variation) ); ?>" value="<?php echo esc_attr( isset($meta['file_path'][0]) ? $meta['download_limit'][0] : null ); ?>" />
  523. </label>
  524. </td>
  525. </tr>
  526. <tr class="virtual options" <?php echo ('virtual' == $product_type ? 'style="display: table-row;"' : 'style="display: none;"');?>>
  527. <td colspan="6">
  528. &nbsp;
  529. </td>
  530. </tr>
  531. <?php do_action( 'jigoshop_variable_product_table_end' , $variation, $attributes)?>
  532. </tbody>
  533. </table>
  534. </div>
  535. </div>
  536. <?php
  537. // Flush & return the buffer
  538. return ob_get_clean();
  539. }
  540. } new jigoshop_product_meta_variable();