0

Using WP 3.8.1, I have a Custom Post Type which is called "Sport" and it has a Metdabox - medata data as enter image description here

I do not need to set up online shopping but I world like to add Price of my products to any Sport CPT and enable updating the Price in the WP table by Checking the Sale on checkbox and specifying sale amount or presentage. so the out put looks like enter image description here I know some part of job can be done by JavaScript(Like adding Sale class to Price or adding sale icon to box) on checkbox but on WP side I also need to update the table to take new price also be able to list all on sale Items for each CPT.

Can you please let me know how to do this? and this is the code:

<?php
/* Custom Meta Boxex */
add_action('add_meta_boxes', 'cpt_metadata_add');
add_action('save_post', 'save_options');
function cpt_metadata_add()
{
    add_meta_box(
        "prodInfo-meta",
        "New Dress Shoe Attributes ",
        "render_meta_elemnts",
        "sport",
        "normal",
        "low"
    );
}
function render_meta_elemnts()
{
    global $post;
    $values  = get_post_custom( $post->ID );
    $price   = isset( $values['metadata_price'] ) ? esc_attr( $values['metadata_price'][0] ) : '';
    $sale    = isset( $values['metadata_sale'] ) ? esc_attr( $values['metadata_sale'][0] ) : '';
    $saleamount  = isset( $values['metadata_sale_amount'] ) ? esc_attr( $values['metadata_sale_amount'][0] ) : '';
    $salepercentage = isset( $values['metadata_sale_percentage'] ) ? esc_attr( $values['metadata_sale_percentage'][0] ) : '';
    wp_nonce_field( 'my_meta_box_nonce', 'meta_box_nonce' );

?>
<table>
<tr>
  <td><?php echo '<label for="metadata_price">Price : $</label>'; ?></td>
  <td><?php echo '<input name="metadata_price" value="'. $price . '" id="metadata_price" />'; ?></td>
  <td style="width:25px;"></td>
  <td><?php echo '<label for="metadata_sale">Sale On :</label> <input type="checkbox" name="metadata_sale" id="metadata_sale" <?php checked( $sale, 'on' ); ?> />'; ?></td>
  <td><?php echo '<label for="metadata_sale_percentage">Sale Percentage : %</label>'; ?></td>
  <td><?php echo '<input name="metadata_sale_percentage" value="'. $salepercentage . '" id="metadata_sale_percentage" />'; ?></td>
  <td style="width:25px;"></td>
  <td><?php echo '<label for="metadata_sale_amount">Sale Amount : $</label>'; ?></td>
  <td><?php echo '<input name="metadata_sale_amount" value="'. $saleamount . '" id="metadata_sale_amount" />'; ?></td>
</tr>
</table>
<?php
}
function save_options()
{
    global $post;
if (!isset($_POST['source']) || $post->post_type != 'sport'){
     return $post;
    }
      update_post_meta($post->ID, "price", $_POST['price']);
    }

Update:

<?php
$args = array( 'post_type' => 'sport');
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post();
$meta = get_post_custom($post->ID);
    the_title();
    echo $meta['price'][0];

endwhile;
?>

Update 2

<?php
$args = array( 'post_type' => 'sport');
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post();
$meta = get_post_custom($post->ID);
     if(metadata_sale = checked) {
        echo $meta['metadata_price'][0] - $meta['metadata_sale_percentage'][0];
    }
    else{
       echo $meta['metadata_price'][0];
    }
endwhile;
?>
2
  • Are you having trouble saving the price? or making it show up on the front-end?
    – gdaniel
    Commented Jan 31, 2014 at 21:49
  • Hi gdaniel, to be honest on both but I think I can make the saving part on my own(Hopefuly!) but on frond ens I have no idea how to do the things like looping and listing the sale items Commented Jan 31, 2014 at 21:51

2 Answers 2

0

You should focus on getting it to save first.

There are endless amount of tutorials online on how to do it, but I would recommend using a plugin called Advanced Custom Fields. That let's you create custom fields in specific pages/posts, without writing any code. This plugin also provides you with functions to use on the front-end to get the content.

However if you want to do it yourself, the data is saved to the postmeta table. You will need to use this function get_post_meta() to retrieve that data.

See the codex: http://codex.wordpress.org/Function_Reference/get_post_meta

Once you can retrieve the data, it's a matter of checking whether the sales prices exists or not. If it does, add a css class to the original price to cross it off. And then display the new price. If there's no sale price... do nothing.

<?php
$args = array( 'post_type' => 'sport');
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post();
$meta = get_post_custom($post->ID);
    the_title();
    echo $meta['price'][0];

    //Assuming that $meta['price'][0] holds your regular price
    //Assuming that $meta['sale'][0] holds your sale price

    if(isset($meta['sale'][0])){

        echo "<div class='sale-price'>" . $meta['sale'][0] . "</div>";

        echo "<div class='old-price'>" . $meta['price'][0] . "</div>";

    }else{

        echo "<div class='regular-price'>" . $meta['price'][0] . "</div>";

    }


endwhile;
?>
5
  • Thanks gdaniel I prefer to go with my own code but what about my question? let say that I have checked the get_post_meta() and figure out that the metadata_sale is checked so how can I update the item's price from metadata_sale_amount and metadata_sale_percentage?! Commented Jan 31, 2014 at 22:21
  • I would need to see the code of where the product is being displayed. You should have a loop that display your products. if it's a post... should be under index.php. If it's a page. Could be under page.php or a custom template.
    – gdaniel
    Commented Jan 31, 2014 at 22:28
  • Ok let's say I have a page called Products with a custom wp loop to list all items under Sport Custom Post Type. now How I can add those CSS classes to the page and Update the actual value in the table? Commented Jan 31, 2014 at 22:33
  • Can you please take alook at above Updated loop? Commented Jan 31, 2014 at 22:36
  • I added some code to my answer. I just don't know what you mean by "Update the actual value in the table?"
    – gdaniel
    Commented Jan 31, 2014 at 22:59
2

First, you need to access to the form data and save it correctly. For example, you are checking if $_POST['source'] is set, but there is no input with name="source" in your form, so the update_post_meta is not executed. Even it update_post_meta would be executed, you are trying to store $_POST['price'] but in your form, again, there is no a price input.

In a quick adaption:

class Price_Metabox
{
/**
 * This is our constructor
 *
 * @return Price_Metabox
 */
public function __construct() {
    add_action( 'add_meta_boxes',          array( $this, 'metabox_add' ) );
    add_action( 'save_post',               array( $this, 'price_save_postdata') );
}

/**
 * Add the Metabox
 *
 */
public function metabox_add() {
    // Add Metabox
    add_meta_box(
                     'prodInfo-meta',
                     "New Dress Shoe Attributes",
                      array( $this, 'render_meta_elemnts' ),
                      'post',
                      'normal',
                      'low'
                 );

}

/**
 * Build the Metabox
 *
 * @param object $post
 *
 */

public function render_meta_elemnts( $post ) {
        $values  = get_post_custom( $post->ID );
        $price   = isset( $values['metadata_price'] ) ? esc_attr( $values['metadata_price'][0] ) : '';
        $sale    = isset( $values['metadata_sale'] ) ? 'checked' : '';
        $salepercentage = isset( $values['metadata_sale_percentage'] ) ? esc_attr( $values['metadata_sale_percentage'][0] ) : '';
        $finalprice = isset( $values['metadata_final_price'] ) ? esc_attr( $values['metadata_final_price'][0] ) : '';
        wp_nonce_field( plugin_basename( __FILE__ ), 'prodInfo_noncename' )

        ?>
<table>
  <tr>
    <td><?php echo '<label for="metadata_price">Price : $</label>'; ?></td>
    <td><?php echo '<input name="metadata_price" value="'. $price . '" id="metadata_price" />'; ?></td>
    <td style="width:25px;"></td>
    <td><?php echo '<label for="metadata_sale">Sale On :</label> <input type="checkbox" name="metadata_sale" id="metadata_sale" '.$sale.'/>'; ?></td>
    <td><?php echo '<label for="metadata_sale_percentage">Sale Percentage : %</label>'; ?></td>
    <td><?php echo '<input name="metadata_sale_percentage" value="'. $salepercentage . '" id="metadata_sale_percentage" />'; ?></td>
    <td><?php echo '<label for="metadata_final_price">Final price : $</label>'; ?></td>
    <td><?php echo '<input name="metadata_final_price" value="'. $finalprice . '" id="metadata_final_price" />'; ?></td>
  </tr>
</table>
<?php
}

/**
 * Save post meta data
 *
 * This function will save the images ids as post meta data (comma separated string).
 *
 */

    public function price_save_postdata($post_id){

       // First we need to check if the current user is authorised to do this action.
       //Currently capabilities of property post type is the same as normal post type
      if ( isset($_POST['post_type']) && 'post' == $_POST['post_type'] ) {
        if ( !current_user_can( 'edit_post', $post_id ) ) return;
       }

     // Secondly we need to check if the user intended to change this value.
     if ( !isset( $_POST['prodInfo_noncename'] ) || ! wp_verify_nonce( $_POST['prodInfo_noncename'], plugin_basename( __FILE__ ) ) )
        return;

        // Thirdly we can save the value to the database
    if(isset($_POST['metadata_price']) ):
            //Don't forget sanitize
        update_post_meta($post_id, 'metadata_price', intval( $_POST['metadata_price'] ) );
    else:
        if (isset($post_id)) {
        delete_post_meta($post_id, 'metadata_price');
        }
    endif;  

    if(isset($_POST['metadata_sale']) ):
            //Don't forget sanitize
        update_post_meta($post_id, 'metadata_sale', 1 );
    else:
        if (isset($post_id)) {
        delete_post_meta($post_id, 'metadata_sale');
        }
    endif;

    if(isset($_POST['metadata_sale_percentage']) ):
            //Don't forget sanitize
        update_post_meta($post_id, 'metadata_sale_percentage', intval( $_POST['metadata_sale_percentage'] ) );
        if ( $_POST['metadata_sale_percentage'] > 0 ) {
                         $finalprice  = $_POST['metadata_price'] - ($_POST['metadata_sale_percentage'] * $_POST['metadata_price'])/100;
                         update_post_meta($post_id, 'metadata_final_price', $finalprice );
                    } else {
                         delete_post_meta($post_id, 'metadata_final_price');
                    }
    else:
        if (isset($post_id)) {
        delete_post_meta($post_id, 'metadata_sale_percentage');
        }
    endif;

    }

}

// Instantiate our class
$Price_Metabox = new Price_Metabox();

Then, to show the meta values:

$meta = get_post_custom($post->ID);
echo 'Price: ' . $meta['metadata_price'][0];
if($meta['metadata_sale'][0] > 0){
    echo 'Discount (%): ' . $meta['metadata_sale_percentage'][0];
    echo 'Final price: ' . $meta['metadata_final_price'][0];
 }

Remember that is just a quick code. It can have erros or it may need some improvements for production environment.

Also, I suggest to use a taxonomy term to group products with discount and use custom fields for the price, discount, etc.

5
  • Wow! cybnet, thanks for you perfect correction and explanation on my snippet! But I still didn't get my answer.What I want to do is displaying discounted price after checking if the metadata_sale is checked or not? something like if(metadata_sale = checked) { echo $meta['metadata_price'][0] - $meta['metadata_sale_percentage'][0]; } else{ echo $meta['metadata_price'][0]; } Commented Feb 1, 2014 at 2:45
  • Can you please take a look at update 2 for this? Commented Feb 1, 2014 at 2:48
  • Sorry, I thought you had a correct answer already as you marked this question as resolved by the gdaniel reply
    – cybmeta
    Commented Feb 1, 2014 at 10:32
  • Thanks cybnet, gdaniel code is returning what I was looking for but I am not sure if that is the best way to do that. Commented Feb 1, 2014 at 22:41
  • If you combine your code with the code of gdaniel is not possible you get what you are asking for. Think on it. With your code, the meta data is not even sotored in the database, so, how can then returns what you are looking for?
    – cybmeta
    Commented Feb 2, 2014 at 8:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.