I am using a function to add custom meta to products. I have used the following hooks for SHOW on Product Loop woocommerce_after_shop_loop_item and Product Single Page woocommerce_product_meta_end.
So, when applying to get the same results on CART PAGE product/item by using the hook
woocommerce_after_cart_item_name it doesn’t work with no results.
Why isn’t the hook woocommerce_after_cart_item_name working if it works with the other previous hooks mentioned?
This the code I am using. I just change the hook to make it to show in Product Loop and Product Single Page, need it to show on cart Products as well. I was just wondering why it doesn't work with cart item hook..
public function woocommerce_after_cart_item_name()
{
global $product;
if ( !PluginOptions::value('shop_season') && !PluginOptions::value('shop_car_type') )
return;
$product_id = $product->get_id();
$season = get_post_meta( $product_id, 'season', true );
$car_type = get_post_meta( $product_id, 'car_type', true );
$tips_seasons = $this->ui_tips_season();
$tips_car_types = $this->ui_tips_car_types();
?>
<div class="tyre-details tyre-tips">
<?php if ( PluginOptions::value('shop_season') && $season ): ?>
<?php echo $tips_seasons[ strtolower($season) ]; ?>
<?php endif ?>
<?php if ( PluginOptions::value('shop_car_type') && $car_type ): ?>
<?php echo $tips_car_types[ strtolower($car_type) ]; ?>
<?php endif ?>
</div>
<?php
}
It is from a plugin. I was just given this code from woocommerce support but i do not know how to complete it. He says to replace with my meta_keys in the code which I will post below here. Can you help me finish this? or tell me where I need to replace. My meta_keys are $season and $car-type but i don't know how to apply with the code provided by woocommerce.
// Display custom cart item meta data (in cart and checkout)
add_filter( 'woocommerce_get_item_data', 'display_cart_item_custom_meta_data', 10, 2 );
function display_cart_item_custom_meta_data( $item_data, $cart_item ) {
$meta_key = 'PR CODE';
if ( isset($cart_item['add_size']) && isset($cart_item['add_size'] [$meta_key]) ) {
$item_data[] = array(
'key' => $meta_key,
'value' => $cart_item['add_size'][$meta_key],
);
}
return $item_data;
}
// Save cart item custom meta as order item meta data and display it everywhere on orders and email notifications.
add_action( 'woocommerce_checkout_create_order_line_item', 'save_cart_item_custom_meta_as_order_item_meta', 10, 4 );
function save_cart_item_custom_meta_as_order_item_meta( $item, $cart_item_key, $values, $order ) {
$meta_key = 'PR CODE';
if ( isset($values['add_size']) && isset($values['add_size'][$meta_key]) ) {
$item->update_meta_data( $meta_key, $values['add_size'][$meta_key] );
}
}
I located the ClassName (class FeatureTyreTips) and added that to the code you provided. I entered this in functions.php and it said fatal error when loading the cart page. I also tried placing it in the cart.php with same results...and I tried in the same plugin file where this code came from originally. All 3 locations did not work...only difference was that it did not show fatal error when adding and activating your new code in the plugin file when loading cart page. Any ideas? grazie Vdgeatano
The "Fatal Error" is most likely due to the fact that "the non-static method cannot be called statically": PHP - Static methods
I have now corrected the code.
Considering that the class name that was missing in your code is FeatureTyreTips, the correct code to add some text after the product name is:
add_action( 'woocommerce_after_cart_item_name', 'add_custom_text_after_cart_item_name', 10, 2 );
function add_custom_text_after_cart_item_name( $cart_item, $cart_item_key ) {
// create an instance of the "PluginOptions" class
$PluginOptions = new PluginOptions();
if ( ! $PluginOptions->value( 'shop_season' ) && ! $PluginOptions->value( 'shop_car_type' ) ) {
return;
}
$product = $cart_item['data'];
$season = get_post_meta( $product->get_id(), 'season', true );
$car_type = get_post_meta( $product->get_id(), 'car_type', true );
// create an instance of the "FeatureTyreTips" class
$FeatureTyreTips = new FeatureTyreTips();
$tips_seasons = $FeatureTyreTips->ui_tips_season();
$tips_car_types = $FeatureTyreTips->ui_tips_car_types();
if ( ! $PluginOptions->value('shop_season') || ! $season ) {
$season = '';
}
if ( ! $PluginOptions->value('shop_car_type') || ! $car_type ) {
$car_type = '';
}
$html = '<div class="tyre-details tyre-tips">' . trim( $season . ' ' . $car_type ) . '</div>';
echo $html;
}
The code has been tested (where possible) and works.It needs to be added to your theme's functions.php file or in your plugin.
Related
Hello I am creating a woocommerce wordpress website and I'm trying to replace the default reviews display with our own integration from Bazaarvoice. so I calledback the reviews tab to display my own function that gets the model number of the product and puts it into the code to display the bazaarvoice review display. The code works except that global $product doesn't work because I don't really know how to use hooks. I know the add_action for function bv_reviews_tab isn't correct so I'm not really sure what I am supposed to be putting there. I have been racking my head all day
add_filter( 'woocommerce_product_tabs', 'woo_renam_tabs', 98 );
function woo_renam_tabs( $tabs ) {
$tabs['additional_information']['title'] = __( 'Product Data' ); // Rename the additional information tab
$tabs['additional_information']['callback'] = 'woocommerce_product_additional_information_tab';
$tabs['reviews']['callback'] = 'bv_reviews_tab';
return $tabs;
}
add_action( 'woocommerce_product_tabs', ' bv_reviews_tab' );
function bv_reviews_tab( ) {
global $product;
if ( $product->is_type('simple' ) ) {
$model = esc_attr( get_post_meta( $product->get_id(), '_model_number', true ) );
}
elseif ( $product->is_type('variable' ) ) {
// Get childIDs in an array
$children_ids = $product->get_children();
// Loop
foreach ( $children_ids as $child_id ) {
// Get product
$product = wc_get_product( $child_id );
$model = esc_attr( get_post_meta( $child_id, '_model_number', true ) );
}
}
?>
<div
data-bv-show="reviews"
data-bv-product-id= "<?php echo $model; ?>"
>
</div>
<?php
}
There is no need of add_action in this case. The callback value given in the woo_renam_tabs function will trigger your custom function. Remove that add_action line and you should be good to go. global $product will also work.
Also, you will need to give a title to the reviews tab and ensure reviews tab is enabled in the WooCommerce >Settings > Products
This is the code that I have tested and is working:
add_filter( 'woocommerce_product_tabs', 'woo_renam_tabs', 98 );
function woo_renam_tabs( $tabs ) {
$tabs['additional_information']['title'] = __( 'Product Data' ); // Rename the additional information tab
$tabs['additional_information']['callback'] = 'woocommerce_product_additional_information_tab';
$tabs['reviews']['title'] = __( 'Reviews' ); ;
$tabs['reviews']['callback'] = 'bv_reviews_tab';
return $tabs;
}
function bv_reviews_tab() {
global $product;
?>
<div data-bv-show="reviews">
<?php echo $product->get_name();?>
</div>
<?php
}
I'm using a plugin for wordpress-woocommerce called Woocommerce Cart PDF (https://wordpress.org/plugins/wc-cart-pdf/). It generates a pdf-link of the current cart, but is located on the cart page.
I have a combined cart and checkout page so the link does not appear on my website. I don't have the knowledge on how to edit the plugin files myself for it to appear on my cart page.
I've tried the wordpress plugin support forum for this specific plugin, but no answer.
/**
* Generates the PDF for download
*
* #return void
*/
function wc_cart_pdf_process_download() {
if( ! function_exists( 'WC' ) ) {
return;
}
if( ! isset( $_GET['cart-pdf'] ) ) {
return;
}
if( ! is_cart() || WC()->cart->is_empty() ) {
return;
}
if( ! isset( $_GET['_wpnonce'] ) || ! wp_verify_nonce( $_GET['_wpnonce'], 'cart-pdf' ) ) {
wc_add_notice( __( 'Invalid nonce. Unable to process PDF for download.', 'wc_cart_pdf' ), 'error' );
return;
}
$dompdf = new \Dompdf\Dompdf();
$content = $css = '';
$cart_table = wc_locate_template( 'cart-table.php', '/woocommerce/wc-cart-pdf/', __DIR__ . '/templates/' );
$css = wc_locate_template( 'pdf-styles.php', '/woocommerce/wc-cart-pdf/', __DIR__ . '/templates/' );
do_action( 'wc_cart_pdf_before_process' );
if( file_exists( $cart_table ) ) {
ob_start();
include $cart_table;
$content = ob_get_clean();
}
if( file_exists( $css ) ) {
ob_start();
include $css;
$css = apply_filters( 'woocommerce_email_styles', ob_get_clean() );
}
$dompdf->loadHtml( '<style>' . $css . '</style>' . $content );
$dompdf->setPaper( 'A4', 'portrait' );
$dompdf->render();
$dompdf->stream(
apply_filters( 'wc_cart_pdf_filename', 'WC_Cart-' . date( 'Ymd' ) . bin2hex( openssl_random_pseudo_bytes( 5 ) ) ) . '.pdf',
/**
* 'compress' => 1 or 0 - apply content stream compression, this is on (1) by default
* 'Attachment' => 1 or 0 - if 1, force the browser to open a download dialog, on (1) by default
*/
apply_filters( 'wc_cart_pdf_stream_options', array( 'compress' => 1, 'Attachment' => 1 ) )
);
exit;
}
add_action( 'template_redirect', 'wc_cart_pdf_process_download' );
if( ! function_exists( 'wc_cart_pdf_button' ) ) {
/**
* Renders the download cart as PDF button
*
* #return void
*/
function wc_cart_pdf_button() {
if( ! is_cart() || WC()->cart->is_empty() ) {
return;
}
?>
<a href="<?php echo esc_url( wp_nonce_url( add_query_arg( array( 'cart-pdf' => '1' ), wc_get_cart_url() ), 'cart-pdf' ) );?>" class="cart-pdf-button button" target="_blank">
<?php esc_html_e( 'Download Cart as PDF', 'wc-cart-pdf' ); ?>
</a>
<?php
}
}
add_action( 'woocommerce_proceed_to_checkout', 'wc_cart_pdf_button', 21 );
This might be the incorrect part of the functions in the plugin, but I hop I got it right.
The wc_cart_pdf_process_download() function isn't really relevant. The comment states that it "Generates the PDF for download". What it's doing is responding when the user visits the PDF link by generating the requested PDF file. The important function is the one beneath that, wc_cart_pdf_button().
Now that we know the function we're interested in, what's next? In your question, you suggested editing the plugin files however it's important to avoid doing that. Editing your plugin files is a sure-fire way to guarantee the changes you make get overwritten the next time you update.
You have a couple of options:
Create a mini feature plugin.
Add the code to the bottom of your (hopefully child) theme's functions.php file.
The first option would be the recommended approach but that's going to take us well beyond the scope of the question. Placing the code in a child theme's functions.php file will be adequate for getting you up and running.
Okay, so now we know what the code we want to modify is and where we're going to store those modifications. Let's break down the actual code:
if( ! is_cart() || WC()->cart->is_empty() ) {
return;
}
This checks two things, are we on the cart page and does the cart contain items? If either is false, we're going to bail out early. You're on the checkout page, not the cart page, so even if this function were to be called, it wouldn't make it past this conditional.
<a href="<?php echo esc_url( wp_nonce_url( add_query_arg( array( 'cart-pdf' => '1' ), wc_get_cart_url() ), 'cart-pdf' ) );?>" class="cart-pdf-button button" target="_blank">
<?php esc_html_e( 'Download Cart as PDF', 'wc-cart-pdf' ); ?>
</a>
If those two previous checks passed, generate the button output.
add_action( 'woocommerce_proceed_to_checkout', 'wc_cart_pdf_button', 21 );
This executes the code on the woocommerce_proceed_to_checkout hook which fires after the cart totals on the cart page. The same action is used by the checkout button itself.
We need to write our own function that displays that same output on the checkout page. Without knowing where you'd like the button to appear, I can't suggest which action to use. I'm using woocommerce_checkout_order_review with a priority that'll put it between the order table and the payment options. If you need to reposition it, you'll have to go through those hooks and find somewhere that feels appropriate.
You did mention in your question that this is necessary because you have your cart and checkout pages combined. You may require a completely different hook, again there's no way for me to know based on your question alone.
Here's the final code:
function stackoverflow_wc_checkout_pdf_button() {
// We're on the checkout page based on the action.
// Highly unlikely we need the is_empty() check but it can't hurt if you may find yourself reusing elsewhere.
if ( WC()->cart->is_empty() ) {
return;
} ?>
<a href="<?php echo esc_url( wp_nonce_url( add_query_arg( array( 'cart-pdf' => '1' ), wc_get_cart_url() ), 'cart-pdf' ) );?>" class="cart-pdf-button button" target="_blank">
<?php esc_html_e( 'Download Cart as PDF', 'wc-cart-pdf' ); ?>
</a>
<?php
}
add_action( 'woocommerce_checkout_order_review', 'stackoverflow_wc_checkout_pdf_button', 15 );
I am writing a 404.php for wordpress. I have the plugin 'rolescoper' installed, and some pages require the user be logged in to view. Rolescoper doesn't offer any way to distinguish between a page not found (404) and a permission denied (403).
I've been able to build this functionality into my pages using the following code:
$the_query = new WP_Query ( 'pagename=' . $_SERVER['REQUEST_URI'] );
$is_valid_page = ! empty ( $the_query -> queried_object -> post_title );
But, surprisingly, the same method does does not work for posts:
$args = array (
'post_type' => 'post',
'name' => str_replace ( "/", "", $_SERVER['REQUEST_URI'] )
);
$the_post_query = new WP_Query ( $args );
$is_valid_post = ! empty ( $the_post_query -> queried_object -> post_title );
When I do a var_dump on $the_post_query i get something that shows 0 results found. I am sure that the page I'm checking for exists.
Any idea how to use wp_query() to query for a post by slug?
Thanks!
After digging through the docs, I found that Rolescoper provided a nice function, is_restricted_rs(), for solving this problem:
//get the slug requested
$slug = $_SERVER [ 'REQUEST_URI' ];
//First check if it's a page and restricted
$page_id = get_page_by_path ( $slug )->ID;
$page_restricted = is_restricted_rs ( $page_id );
//Then check if it's a post and restricted
$args = array(
'name' => $slug,
'post_type' => 'post',
'post_status' => 'publish',
'numberposts' => 1
);
$my_posts = get_posts($args);
if ( $my_posts ) {
$post_id = $my_posts[0]->ID;
}
$post_restricted = is_restricted_rs ( $post_id );
//then set $content_restricted for use below
$content_restricted = $post_restricted || $page_restricted;
The rolescoper plugin has become defunct and we developed a solution which does not require any external plugin. Instead, we added some code to our theme and added a custom field to each page that we wanted to restrict access to.
This isn't as robust as rolescoper was, but for our use case it was perfect. We have only a few user classes and so I just hardcode the different classes and that's enough for us. I'm sure a similar solution could be used for more complex cases, especially if you expanded on the custom UI code.
I happened to name the field "dhamma_perms" but you could name it anything you want:
function is_restricted() {
return item_restricted(get_post(), wp_get_current_user());
}
function item_restricted($page, $user) {
$dhamma_perms = get_post_meta($page->ID, "dhamma_perms", true);
$requires_os = $dhamma_perms == "oldstudents";
$requires_worker = $dhamma_perms == "workers";
if (!is_user_logged_in()) {
return $requires_os || $requires_worker;
} else if (get_userdata($user->ID)->user_login == "oldstudent") {
return $requires_worker;
} else {
//dhammaworkers and all named users have full read access
return false;
}
}
I then modified any page which could be restricted to have code like this at the top:
<?php get_header(); ?>
<?php if (is_restricted()) : ?>
<?php show_404(); ?> //I just pasted the full content of our 404 page into a function. The 404 page shows a faux-403 page (WP doesn't have real 403 pages) if the content exists but is restricted.
<?php else: ?>
//show normal page stuff
I also modified the header.php to have a proper title for 404 and 403 pages:
<?php if (is_restricted()) : ?>
<title> <?php echo "Login Required " . get_theme_mod('dhamma_title_separator') . " " . get_bloginfo('name'); ?></title>
<?php else: ?>
<title><?php wp_title( get_theme_mod('dhamma_title_separator'), true, "right" ); bloginfo('name'); ?></title>
<? endif; ?>
Finally, I added a custom UI to posts and pages so it's easy to select permissions:
//Register the permissions metabox for posts and pages
function add_perms_box( $post ) {
$screens = [ 'post', 'page', 'wporg_cpt' ];
foreach ( $screens as $screen ) {
add_meta_box(
'dhamma_perms_box', // Unique ID
'Permissions', // Box title
'perms_box_html', // Content callback, must be of type callable
$screens // Post type
);
}
}
function perms_box_html() {
$value = get_post_meta(get_the_ID(), "dhamma_perms", true);
?>
<select name="dhamma_perms" id="dhamma_perms" class="postbox">
<option value="public" <?php selected($value, 'public');?>>Public</option>
<option value="oldstudents" <?php selected($value, 'oldstudents');?>>Old Students Only</option>
<option value="workers" <?php selected($value, 'workers');?>>Dhamma Workers Only</option>
</select>
<?php
}
add_action('add_meta_boxes', 'add_perms_box');
function dhamma_meta_save( $post_id ) {
// Checks save status
$is_autosave = wp_is_post_autosave( $post_id );
$is_revision = wp_is_post_revision( $post_id );
// Exits script depending on save status
if ( $is_autosave || $is_revision ) {
return;
}
// Checks for input and sanitizes/saves if needed
if( isset( $_POST[ 'dhamma_perms' ] ) ) {
update_post_meta( $post_id, 'dhamma_perms', $_POST[ 'dhamma_perms' ] );
}
}
add_action( 'save_post', 'dhamma_meta_save' );
This created a new dropdown on each page and post for us:
I hope this is helpful for anyone else trying to get some simple permissions on a wordpress site!
I have created custom user taxonomy for user and its working good for single taxonomy.
From Bellow reference guide i have created custom user taxonomy.
Reference guide:- http://justintadlock.com/archives/2011/10/20/custom-user-taxonomies-in-wordpress
Bellow is structure of taxonomy
(registered taxonomy) profession
Dietitian (under the profession )
(registered taxonomy) city
NewYork(under the city)
my slug name name expert
Here i want to display filter result which user is Dietitian in NewYork city.so it will display all user which have selected above option in profile.
Now i want the url something like www.test.com/expert/dietitian/newyork
with user which have selected Dietitian , NewYork in user profile. And is there any solution to combine Dietitian,NewYork
The url with single terms works like:- www.test.com/expert/dietitian/
I am assuming that you have spend a great deal of time on the tutorial of justintadlock, so I will get involved only with the parts of it that are needed for the multiple taxonomy filtering and display on the front-end.
Before your read the long text, you can have a taste at http://playground.georgemanousarides.com/
So, first thing's first.
The logical base is the same for both SINGLE TAXONOMY and MULTIPLE TAXONOMIES.
After having registered the taxonomies and their terms and have done all the work needed wp-admin wise, we will need:
A) A page (lets call it TAX-QUERY PAGE) in which visitors can select the taxonomy query.
B) Another page (lets call it TAX-RESULTS PAGE) in which the results of TAX-QUERY PAGE will be displayed.
Let's dive in
SINGLE TAXONOMY
TAX-QUERY PAGE
After following the tutorial, the page that you display the taxonomies links should look, on its primal form, like this:
single taxonomy tax-query page
Visitors "Select" which taxonomy they want to see by simply clicking on the links provided.
Note that:
A) The links for:
Proffession will be like:
www.example.com/user/profession/developer/
City will be like:
www.example.com/user/city/gotham/
B) The slugs "user/city" and "user/profession" are defined at the function: my_register_user_taxonomy >> register_taxonomy >> rewrite >> slug
TAX-RESULTS PAGE
Clicking on the links mentioned above takes you to a page ( which needs to be defined by you of course ) that displays all the users under the same taxonomy-term.
This is achieved by creating custom taxonomy templates.
You can create the taxonomy-profession-developer.php file to handle a single taxonomy and term, or the taxonomy-profession.php to handle a single taxonomy and all its' terms, or the taxonomy.php for all taxonomies and their terms.
In my opinion, if you don't want your server to be flooded with template files which are manually created by you, you should use the taxonomy.php and make a general teplate for all taxonomies which descriminates the results you want to display automatically.
Note that:
A) To itterate through users and fetch only those under the desired taxonomy-term, a custom query is needed ( in the taxonomy.php file ), as mentioned and explained in the tutorial.
B) Permalinks should be on Post Name option from the wp-admin >> settings >> permalinks so that wordpress can find your taxonomies, fetch the file taxonomy.php and provide usefull info about the selected taxonomy that can be used in the taxonomy.php file.
MULTIPLE TAXONOMIES
TAX-QUERY PAGE
We need to create a page where visitors will select terms from the custom taxonomies. This page will provide the TAX-RESULTS PAGE ( taxonomy.php ) with the needed terms through a link (as get variables**) so as to make a query.
**In order to have pretty permalinks in the TAX-RESULTS PAGE we need to add the following rewrite function (found it here) to the function.php, and refresh the permalinks in wp-admin:
function eg_add_rewrite_rules() {
global $wp_rewrite;
$new_rules = array(
'user/(profession|city)/(.+?)/(profession|city)/(.+?)/?$' => 'index.php?post_type=eg_event&' . $wp_rewrite->preg_index(1) . '=' . $wp_rewrite->preg_index(2) . '&' . $wp_rewrite->preg_index(3) . '=' . $wp_rewrite->preg_index(4),
'user/(profession|city)/(.+)/?$' => 'index.php?post_type=eg_event&' . $wp_rewrite->preg_index(1) . '=' . $wp_rewrite->preg_index(2)
);
$wp_rewrite->rules = $new_rules + $wp_rewrite->rules;
}
add_action( 'generate_rewrite_rules', 'eg_add_rewrite_rules' );
Note that
If you register more taxonomies the "profession|city" in the function should become "profession|city|tax1|tax2|tax3".
So the TAX-QUERY PAGE will be:
HTML
<div id="taxonomies">
<h1>Find your professional</h1>
<form>
<?php if ( $taxonomies = get_object_taxonomies( 'user' ) ) : //get all taxonomies under the object_type "user" ( The second parameter given to the function my_register_user_taxonomy of the tutorial )
foreach ( $taxonomies as $taxonomy ) : ?>
<p>
<ul>
<fieldset id="<?php echo esc_attr( $taxonomy ); ?>"> <!-- group the form by taxonomies -->
<legend><h2>Choose <?php echo $taxonomy; ?></h2></legend>
<?php if ( $terms = get_terms( $taxonomy ) ) : //get taxonomy's terms
foreach ( $terms as $term ) : ?>
<li><input type="checkbox" value="<?php echo esc_attr( $term -> slug ); ?>"> <?php echo $term -> name; ?></li>
<?php endforeach;
endif; ?>
</fieldset>
</ul>
</p>
<?php endforeach;
endif; ?>
</form>
<a id="multiTaxSubmit" href="<?php echo esc_attr( get_home_url() . '/user' ); ?>">SUBMIT</a> <!-- this link is processed by jQuery to provide the taxonomy.php with the proper values. The href attribute is the base url needed by the taxonomy.php -->
</div>
JQUERY ( Can be put in an external file )
$( document ).ready( function() {
$( '#multiTaxSubmit' ).click( function ( event ){
event.preventDefault(); //prevent default link url from loading
var taxQuerySubmit = $( this ),
hasChecked = 0;
querySlug = taxQuerySubmit.attr( 'href' ); //get multitax url base from link href attr
$( '#taxonomies fieldset' ).each( function() { //iterate each taxonomy
var checkedTerms = $( this ).find( 'input:checked' ),
checkedLength = checkedTerms.length; //how many terms has the user selected
if ( checkedLength ) {
hasChecked += checkedLength;
querySlug += '/' + $( this ).attr( 'id' ) + '/'; //add taxonomy slug to query url
checkedTerms.each( function( index, value ) {
var comma = ( index == checkedLength-1 ? '' : ',' );
querySlug += $( this ).val() + comma;
} );
}
} );
if ( hasChecked ) {
window.location = querySlug;
} else {
alert( 'Please enter some criteria.' );
}
} );
} );
TAX-RESULTS PAGE ( taxonomy.php )
<?php
$USERS_BY_TAX = array();
if ( $taxonomies = get_object_taxonomies( 'user' ) ) { //get all taxonomies under the object_type "user" ( The second parameter given to the function my_register_user_taxonomy of the tutorial )
foreach ( $taxonomies as $tax_key => $taxonomy ) {
eval( '$check = $' . $taxonomy . ';' ); // Check if the taxonomy exists in the url. eval outputs $check = $profession, $check = $city etc.
if ( !$check ){
unset( $taxonomies[ $tax_key ] );
continue;
}
eval( '$term_names = explode( ",", $' . $taxonomy . ' );' ); // get terms array from $$taxonomy which gives $profession,$city, the values of which are given through the url as such: $profession="designer,developer"
$USERS_BY_TAX[ $taxonomy ] = array();
foreach ( $term_names as $term_name ) {
$term_obj = get_term_by( 'name', $term_name, $taxonomy ); //get term object for each given term
$users_in_term = get_objects_in_term( $term_obj -> term_id, $taxonomy ); // find users with term
if ( !empty( $users_in_term ) ) {
$USERS_BY_TAX[ $taxonomy ] = $USERS_BY_TAX[ $taxonomy ] + array_fill_keys( $users_in_term, $term_name ) ;
}
}
}
}
/* $USERS_BY_TAX array has all the users for each taxonomy but we only need those who exist in all taxonomies */
if ( $taxonomies ) {
$RESULTS = $USERS_BY_TAX; // keep the initiate array intact
$matched = array_pop( $USERS_BY_TAX ); // first array to compare
$TAXS = $taxonomies;
array_pop( $taxonomies );
if ( !empty( $USERS_BY_TAX ) ) {
foreach ( $taxonomies as $taxonomy ) {
if ( !empty( $USERS_BY_TAX ) ) $matched = array_intersect_key( $matched, $USERS_BY_TAX[ $taxonomy ] );
}
}
}
?>
/* DISPLAY */
<?php if ( $matched ) :
foreach ( array_keys( $matched ) as $user_id ): ?>
<div class="user-entry">
<?php echo get_avatar( get_the_author_meta( 'email', $user_id ), '96' ); ?>
<h2><?php the_author_meta( 'display_name', $user_id ); ?></h2>
<?php if ( in_array( 'profession', $TAXS ) ) : ?><h3>Profession: <?php echo $RESULTS[ 'profession' ][ $user_id ]; ?></h3><?php endif;?>
<?php if ( in_array( 'city', $TAXS ) ) : ?><h3>City: <?php echo $RESULTS[ 'city' ][ $user_id ]; ?></h3><?php endif;?>
<?php echo wpautop( get_the_author_meta( 'description', $user_id ) ); ?>
</div>
<?php endforeach;
else: ?>
<div class="user-entry">
<h2>We are sorry. No results match your criteria.</h2>
<h3>Please go back and search again!</h3>
</div>
<?php endif; ?>
This rewrite rule should work (assuming "profession" and "city" are the taxonomy registered names):
Code:
function custom_rewrite_rules() {
add_rewrite_rule('^profession/(.*)/city/(.*)?', 'index.php?profession=$matches[1]&city=$matches[2]', 'top');
}
add_action('init', 'custom_rewrite_rules');
Remember to flush the rewirte rules after saving this code in your site.
URL :
http://yourdomain.com/profession/dietitian/city/newyork/
To flush the permalinks or rewrite rules from your theme or plugin you need to use the flush_rewrite_rules() function.
<?php
function custom_rewrite_rules() {
flush_rewrite_rules();
add_rewrite_rule( '^products/([^/]*)/([^/]*)/(\d*)?',
'index.php?product_type=$matches[1]&product_brand=$matches[2]&p=$matches[3]',
'top' );
//Post Type: products
//Taxonomy: product_type
//Taxonomy: product_brand
}
add_action('init', 'custom_rewrite_rules');
?>
I am trying to add a new field on my cart.php file.
I actually want to insert a URL field, so user can set a URL for each order item.
I tried to use a code from another post here but I can't get it to work.
The first and the second functions are working but when it comes to the third one, 'woocommerce_get_item_data' the $cart_item['url'] doesn't contain anything even if I add something in the field and I press Update Cart.
$cart_totals[ $cart_item_key ]['url'] from the first function is outputting the right value when the page load.
I don't know what to do now, thanks for any help.
Here is the code
Add the field
cart/cart.php
<td class="product-url">
<?php
$html = sprintf( '<div class="url"><input type="text" name="cart[%s][url]" value="%s" size="4" title="Url" class="input-text url text" /></div>', $cart_item_key, esc_attr( $values['url'] ) );
echo $html;
?>
</td>
functions.php
// get from session your URL variable and add it to item
add_filter('woocommerce_get_cart_item_from_session', 'cart_item_from_session', 99, 3);
function cart_item_from_session( $data, $values, $key ) {
$data['url'] = isset( $values['url'] ) ? $values['url'] : '';
return $data;
}
// this one does the same as woocommerce_update_cart_action() in plugins\woocommerce\woocommerce-functions.php
// but with your URL variable
// this might not be the best way but it works
add_action( 'init', 'update_cart_action', 9);
function update_cart_action() {
global $woocommerce;
if ( ( ! empty( $_POST['update_cart'] ) || ! empty( $_POST['proceed'] ) ) ) {
$cart_totals = isset( $_POST['cart'] ) ? $_POST['cart'] : '';
if ( sizeof( $woocommerce->cart->get_cart() ) > 0 ) {
foreach ( $woocommerce->cart->get_cart() as $cart_item_key => $values ) {
if ( isset( $cart_totals[ $cart_item_key ]['url'] ) ) {
$woocommerce->cart->cart_contents[ $cart_item_key ]['url'] = $cart_totals[ $cart_item_key ]['url'];
}
}
}
}
}
// this is in Order summary. It show Url variable under product name. Same place where Variations are shown.
add_filter( 'woocommerce_get_item_data', 'item_data', 10, 2 );
function item_data( $data, $cart_item ) {
if ( isset( $cart_item['url'] ) ) {
$data['url'] = array('name' => 'Url', 'value' => $cart_item['url']);
}
return $data;
}
// this adds Url as meta in Order for item
add_action ('woocommerce_add_order_item_meta', 'add_item_meta', 10, 2);
function add_item_meta( $item_id, $values ) {
woocommerce_add_order_item_meta( $item_id, 'Url', $values['url'] );
}
Add a textarea field to a WooCommerce cart item
First, we just need to add the textarea field. We use the woocommerce_after_cart_item_name hook so our textarea will appear after the product name.
<?php
/**
* Add a text field to each cart item
*/
function prefix_after_cart_item_name( $cart_item, $cart_item_key ) {
$notes = isset( $cart_item['notes'] ) ? $cart_item['notes'] : '';
printf(
'<div><textarea class="%s" id="cart_notes_%s" data-cart-id="%s">%s</textarea></div>',
'prefix-cart-notes',
$cart_item_key,
$cart_item_key,
$notes
);
}
add_action( 'woocommerce_after_cart_item_name', 'prefix_after_cart_item_name', 10, 2 );
/**
* Enqueue our JS file
*/
function prefix_enqueue_scripts() {
wp_register_script( 'prefix-script', trailingslashit( plugin_dir_url( __FILE__ ) ) . 'update-cart-item-ajax.js', array( 'jquery-blockui' ), time(), true );
wp_localize_script(
'prefix-script',
'prefix_vars',
array(
'ajaxurl' => admin_url( 'admin-ajax.php' )
)
);
wp_enqueue_script( 'prefix-script' );
}
add_action( 'wp_enqueue_scripts', 'prefix_enqueue_scripts' );
´´´
At the moment, the user will be able to enter text into the field but the text won’t save. We are going to use some AJAX to save the text.
The code above not only adds the textarea to the cart item, it also enqueues a JavaScript file ready for our AJAX.
It’s assumed that you’re using the code on this page to create a new plugin. If so, you should create a new JS file with the code below and place the file in the root directory of your plugin.
However, if you’ve added the PHP above to your theme functions.php or as a snippet on your site, you’ll need to change the location of the JS file by updating line 21 of the snippet above to identify the location of the JS file.
´´´
(function($){
$(document).ready(function(){
$('.prefix-cart-notes').on('change keyup paste',function(){
$('.cart_totals').block({
message: null,
overlayCSS: {
background: '#fff',
opacity: 0.6
}
});
var cart_id = $(this).data('cart-id');
$.ajax(
{
type: 'POST',
url: prefix_vars.ajaxurl,
data: {
action: 'prefix_update_cart_notes',
security: $('#woocommerce-cart-nonce').val(),
notes: $('#cart_notes_' + cart_id).val(),
cart_id: cart_id
},
success: function( response ) {
$('.cart_totals').unblock();
}
}
)
});
});
})(jQuery);
´´´
Now, when the user types anything, the contents of the text field get sent back to the server ready to be saved as meta data to the cart item.
´´´
<?php
/**
* Update cart item notes
*/
function prefix_update_cart_notes() {
// Do a nonce check
if( ! isset( $_POST['security'] ) || ! wp_verify_nonce( $_POST['security'], 'woocommerce-cart' ) ) {
wp_send_json( array( 'nonce_fail' => 1 ) );
exit;
}
// Save the notes to the cart meta
$cart = WC()->cart->cart_contents;
$cart_id = $_POST['cart_id'];
$notes = $_POST['notes'];
$cart_item = $cart[$cart_id];
$cart_item['notes'] = $notes;
WC()->cart->cart_contents[$cart_id] = $cart_item;
WC()->cart->set_session();
wp_send_json( array( 'success' => 1 ) );
exit;
}
add_action( 'wp_ajax_prefix_update_cart_notes', 'prefix_update_cart_notes' );
function prefix_checkout_create_order_line_item( $item, $cart_item_key, $values, $order ) {
foreach( $item as $cart_item_key=>$cart_item ) {
if( isset( $cart_item['notes'] ) ) {
$item->add_meta_data( 'notes', $cart_item['notes'], true );
}
}
}
add_action( 'woocommerce_checkout_create_order_line_item', 'prefix_checkout_create_order_line_item', 10, 4 );
´´´
The prefix_update_cart_notes function does a security check using the WooCommerce cart nonce then saves the content of the textarea as meta data in the cart item. You can check out this article for more information about updating cart meta for items that have already been added to the cart.
Add the custom text to the order meta
Finally, we want to pass our meta data to the order so that we can use it after the customer has checked out. The prefix_checkout_create_order_line_item function takes care of that, iterating through each item and saving notes when it finds them.
https://pluginrepublic.com/how-to-add-an-input-field-to-woocommerce-cart-items/